I've run into an issue with webpacker in my rails app during development. Webpacker should also compile when some of the related config files change, but doesn't since they aren't in the app/javascript folder.
Is there to have webpacker also watch additional files for changes?
More detailed:
I load my css through webpacker. For this I'm using TailwindCSS and postCSS. I tend to change the tailwind config file (located in the application root) quite a bit, to automatically generate additional utilities and/or variant.
However, when I change the tailwind config file it doesn't trigger webpacker to recompile on the next page load. It only recompiles when I change one of the files in the app/javascript folder - even if it is just adding an extra blank line. I would like to avoid having to manually trigger webpacker to recompile.
I have changed nothing to the Rails defaults for webpacker.
In config/webpacker.yml, you want to add files and directories to the resolved_paths section.
resolved_paths:
- app/assets
- tailwind.config.js
There’s more information in this article https://rossta.net/blog/why-does-rails-install-both-webpacker-and-sprockets.html
Related
In development mode, all looks great. But when I switch over to production, bootstrap isn't found. When I look at the logs, I see errors like:
ActionController::RoutingError (No route matches [GET] "/packs/js/application-2a5806e943e281221741.js"):
This is true for both CSS and JS. When I look inside public/packs the files do exist in the corresponding subdirectory (js for the .js file, etc). So, webpacker is did it's job but puma isn't finding it. Any ideas? This is an old rails app that was migrated up several versions of rails, so I'm sure there is something I missed when tying everything together.
To expand on Tenzin's comment which I believe is the correct answer to the issue, Rails in development will always re-render assets and serve them. This is slow, but useful for seeing quick changes while developing.
When we want to deploy to production, the issue is Rails begins to serve static files which means that the server is no longer going to render them on every request. It will render them once and serve them forever. With webpacker, you can find the places these assets are served in webpacker.yml
public_root_path: public
public_output_path: packs
So if you are deploying or trying to run production locally, first be sure to compile your assets for production so these static files are created.
rake assets:precompile RAILS_ENV=production
Then make sure that wherever the server is running it has an ENV variable RAILS_SERVE_STATIC_FILES set to anything. As you can see from production.rb,
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
Is simply checking if this variable is present. If it is then it will not re-render as we discussed and it will look for the static files shown in webpacker.yml.
As another small note, if you are using something like a React UI or Bootstrap and the CSS is missing, be sure that you are importing the CSS according to the library's documentation.
For example, in Bootstrap, you will need to create an application.scss file in app/javascript/packs/stylesheets (really wherever in the /javascript folder) and import that in /javascript/packs/application.js.
In application.scss you'll want to
import "~bootstrap/scss/bootstrap"
This is of course after you have added Bootstrap to your package.json with something like
yarn add bootstrap
I'm trying to configure Webpacker to work with a Rails engine. I'm specifically interested in how people are setting up their webpacker.yml to move their engine's assets to the main app's /public/ folder.
First, I've followed the Webpacker instructions for Using in Rails Engines. However, Step 7 stumps me. The idea here is to set the public_root_path to your app's /public folder. I could obviously hard-code the correct path on my personal machine, but that's unsustainable for production or other devs. I can't rely on ERB to have a dynamic path either.
I also tried the second option of Step 7 which involves middleware, but it didn't seem to have any effect.
I ultimately want to be able to import JavaScript from the engine into the main app from the app/javascript/packs/application.js file. How do I get Webpacker to find the files from the engine without hard-coding the path?
Using the default configuration of rails/webpacker I could not read a file through the <%= asset_pack_path 'images/calendar.png' %> helper in a view.
Reading the docs it seems easy to do, but something goes wrong trying access the page:
Webpacker can't find application.css in /path/manifest.json. Possible causes:
You want to set webpacker.yml value of compile to true for your environment
unless you are using the webpack -w or the webpack-dev-server.
Webpack has not yet re-run to reflect updates.
You have misconfigured Webpacker's config/webpacker.yml file.
Your Webpack configuration is not creating a manifest.
Your manifest contains:
Am I missing some configuration?
It seems a docs misundertand as the answer:
asset_pack_path only references assets used as pack (i.e. JS packs file) or assets used inside a pack like a font, image or styles referenced that's why it's not present inside manifest.json. asset_pack_path doesn't look inside any folder like rails view helpers for assets.
Perhaps use Rails image_path helper if you want to reference images that’s not used inside packs.
The webpacker documention tells us about using:
require.context('../images', true)
in an entrypoint (app/javascript/packs), to include all the images under app/javascript/images into the exported assets.
If you are using webpacker6.pre/beta, there is currently a bug which flattens nested folders, though.
I'm wondering what the best way is to use images & fonts from bower packages with middleman. As an example, I'm trying to add the slick.js carousel to my project. It's on bower and includes css, js, images, and fonts in the bower code.
With middleman, I have things set up where I've added the bower_components directory to the path for sprockets and compass, so the scss and js files are getting compiled correctly and working fine.
But the images and fonts aren't getting put anywhere where they'll be used. The slick.js library uses scss and is set up to use the compass image-url and font-url functions if they exist, meaning I need to somehow get the assets from the bower_components directory to be served from the same place as all my own images and fonts, and in a way that works in both the development middleman server mode as well as when running build.
How do I do this?
Obviously possible solutions are just to vendorize the slick.js library directly into my code or include it from the cdn where it's already hosted and not worry about not having it compiled into my single css and js files. Either could work fine but I'm wondering about the general case, surely this is common scenario for anyone using bower and middleman.
I figured it out - I thought compass was for requiring scss files and sprockets was just for the js, but middleman also uses sprockets (the middleman-sprockets library) for copying arbitrary static assets.
It's a bit manual and verbose (if there were a lot more files middleman suggests writing a script to auto-discover them by file extension types and import them) but my solution is to include the following in the config.rb file:
# set local vars I'll need to access later
images_dir = 'images'
set :images_dir, images_dir
# ... other config
sprockets.import_asset('slick-carousel/slick/ajax-loader.gif') {|p| "#{images_dir}/ajax-loader.gif"}
I use grunt, but it's the same issue. Generally you have the following options:
-Commit what you need in the bower_components directory right in to source control and reference your resources from there (somewhat recommended especially if something external is down when you are doing a build), or if you don't like exposing bower_components in URLs, create a route that directs to your bower_components folder
-Copy components on build/middleman script execution to a specified path. There will be no resources to check in for this option, you just choose a destination to reference in your code and have middleman copy your components out there.
I've got a Rails site with a Jekyll blog incorporated, using the Bloggy gem.
I'd like a similar look for the main site and the blog, so I want to use the css in app/assets/stylesheets, but those files are in css.scss format. Jekyll (in a Bloggy setup) looks for css in config/jekyll/css, and seems to only want .css files; symlinking the Rails css directory into the Jekyll hierarchy doesn't seem to to work.
Is there a way to take advantage of the asset pipeline so that when I run jekyll:build, SCSS files from the Rails app are made into CSS files, placed in the appropriate jekyll directory, and bundled with the latest Jekyll build as it's placed into the /public/blog folder?
Thanks!
Ended up getting through this by:
Using the jekyll-sass gem to allow automatic transformation of the Rails app's .css.scss into .css.css files. By symlinking the Rails app/assets/stylesheets directory into Bloggy's config/jekyll/css, this put files with the right content but wrong extensions in the correct place.
Writing a rake task to make the .css.css files into .css files.
desc 'Make .css.css files into .css files'
task :css_css do
Dir.glob('public/blog/css/*.css.css').each do |file|
puts `mv #{file} #{file.gsub(/\.css\.css$/, '.css')}`
end
end
Not the prettiest solution, but it works.
#Matthew.. You have a nice solution.. For this part I did some stuffs manually. Like I added config/jekyll/css files as .css extension rather than .css.scss so when we run "rake generate" for bloggy the right format files are created on the folder public/blog/ rather css.scss.
I have made the changes in my bloggy portfolio theme project repository. If you are planning to use my version of code, I have did some changes like added robots.txt, sitemap, and integrated bootstrap to the project. I have also removed all database connections from the rails project since it was showing errors while deploying into heroku.