Sprockets is barely maintained for something that was and seemingly still is central to web apps. It’s needed for the images / CSS part of the asset pipeline. For example, it’s got a parallel execution hang that could be fixed by one line of reconfig, but it’s still in there to confuse the multitudes. See https://github.com/rails/sprockets/issues/640
I also had to help my Rails newbie reconfigure sprockets to put its cache on a separate Docker volume, because of this issue: asset pipeline - `Errno::EExist` error with sprockets when running rails in dev - Stack Overflow
DHH mentioned in his RailsConf Q&A that he thought Sprockets worked better for CSS/assets than Webpack(er). I would love to know why he thinks that. To me, the both do the same thing - process and copy those files to where they need to go. The default Webpack configuration works for CSS already and I think for other assets, too. While it’s odd to put CSS in app/javascript/packs
, it works well and, if Webpack was the default, it would be one less thing to think about and would allow Sprockets to go into maintenance mode.
I’m sure I’m oversimplifying, but I think even knowing what the perceived advantages of Sprockets over Webpack are would be helpful.
Yes, and having to setup both Webpacker and Sprockets seems - what feels like two different asset pipelines as default - overcomplicated.
Considering webpacker
includes PostCSS (GitHub - rails/webpacker: Use Webpack to manage app-like JavaScript modules in Rails), which makes it more confusing whether to use sprockets or not for new apps.
I think that pre-webpacker 5, the behavior of including a CSS file is a little-counter intuitive, but webpacker 5 should be a little bit better here because of the support for multiple entry files.
FWIW, we found using CSS in Webpacker intuitive even before Webpacker 5. We just load our CSS from our JS entry file, and then the mini-css-extract-plugin
that webpacker uses extracts that into a separate CSS file.
A month ago I finally moved the rest of the JS and CSS that was still in the Sprockets environment over to Webpacker, and it made our assets significantly easier to reason about. Not to mention we were able to add PostCSS-based projects such as TailwindCSS, which I’m not sure how it’s done with Sprockets.
Removing Sprockets also reduced the load time of our test suite. I’ll admit that my MacBook is relatively old, but I’ve regularly seen 3-4s of test suite runtime spent in Sprockets on some kind of synchronization.
If you want to be in the loop with modern frontend development, I don’t see a reason to use Sprockets anymore.
I found the switch to Webpacker to be a confusing journey with clear documentation on how to make a clean migration hard to find. I was able to upgrade existing apps to use Webpacker for JS, but I still have CSS and images in the asset pipeline. My apps deploy to Heroku and I am always paranoid about compiling errors when the assets deploy to from Cloudfront CDN. I haven’t been brave enough to push images and CSS into Webpacker yet. I personally still really like sprockets for images and CSS. Better documentation would go a long way.
Webpacker seems like a fearsome beast. If it’s the way to go, then we need much better guides to explain how to use it for all assets.
Agree with @masterleep, if Webpacker is the way the go we should have a guide that reflects that.
I also agree that if we’re committing to Webpacker, the guides need some significant love or we need more out of the box functionality around it. Part of the magic of Rails is that it just works - and the Webpacker integration, as it is, seems to require a non-trivial amount of effort to match the functionality that we’ve had with Sprockets.
My team found incorporating CSS ultimately just a matter of having the right boilerplate and directory structure, and turning the applicable configuration knobs. However, building our understanding was a real drag.
The real WTF for me was (and remains) that Webpacker lacks a guide, not rating even a single mention or footnote in the Asset Pipeline or Working with JavaScript in Rails guides despite being the only clear path forwards for both. The documentation in the Webpacker repository is not introductory material, it’s all definitely Hard Mode stuff.
Everything practical I know about Webpacker is therefore from trial & error, reading source code, and puts debuggering.
I think part of the problem with Webpacker and CSS is that Webpack itself doesn’t really treat CSS like a first-class citizen. I know that newer versions of Webpack are trying to catch up on this, but it seems like there’s a lot of technical debt in their way.
It sounds like this is a case where Rails, ironically, isn’t nearly opinionated enough, and that a combination of better documentation and a bit more guidance from the framework could really help folks out.
@inopinatus it sounds like your team’s CSS structure works really well for y’all – would you mind sharing more details of what your team does?
My team has also made a lot of strides towards using Webpack exclusively for assets. We’re in the middle of migrating assets from Sprockets to Webpacker. Webpack 5 was a big step up, surprisingly.
I actually really like Webpacker as a npm package because it’s everything you need in terms of modern JS tooling. I agree the docs need some work, but I don’t think it’s an impossible task.
I think there are two great points here:
- Sprockets maintenance is not happening.
- Rails including two tools where each can do everything the other can.
The first point is entirely mea culpa. I’m being the maintainer of Sprockets for years and I inherited the project after the two original authors left it. At the time I was still doing frontend work. After I moved companies I was getting further and further aways from frontend development. This caused my motivation to work on Sprockets to drop since I was not using it anymore in our apps. All that being said, Sprockets is another example of project that could use a motivate contributor and I’m happy to support that person on this.
To the second point, I can’t speak for DHH, but my feeling as a uses is that sprockets were better for CSS and images than Webpack. That could be familiarity bias since I’m more used with Sprockets than Webpack. But, with JavaScript files, Webpack is orders of magnitude better. Our intention were to provide the best for each kind of files. But we are lacking in documentation and guidance. For example, the assets pipeline guide has no mention to Webpacker. We need to fix it. This is another place where the community can help.
Ah yes, the great Sprockets to Webpacker migration! A few years ago, static-site generator Middleman dropped support for Sprockets in favor of external pipelines (eg. Webpacker), because it’s the way of the future!™ …which I can pretty much agree on. But god did it wreak havoc on my codebases and meant I lost the ability to easily configure asset compilation. Nowadays, in Middleman-land, I still tend to avoid any CSS compilation.
Pretty much any time I’ve been in contact with Webpack and it’s configuration, I’ve sunk a few hours into configuring, and after a long day of frustration, went “f— this. I’m going back.” Rinse, repeat, every few months/years. – And that, even if nowadays, I code more stuff with Vue/JS on the front-end than in Rails. – Not a happy one.
That’s pretty much my experience with the Javascript tooling in general. The configuration is horrible, there is boilerplate everywhere, you need to specify everything, and as soon as you go off the very mainstream path (eg. use Coffeescript), you’re on your own with unmaintained Github projects with half a star. Convention-over-configuration – a core tenet of Rails in my opinion, and one of its treasures – is not most JS tools’ forte. These experiences have not instilled good feelings in me.
With that said, I’m always hoping this year is the right one for ease of using Webpacker and other JS stuffs. The day I can throw at it a bunch of Sass, a bunch of Coffee, minimal configuration, and be done with it, I’ll be won over. If there’s one community who can push that forward, on the Rails side and on the Webpacker side, it’s this one.
@Betsy_Haibel Elements of our workflow include:
Strict use of modules and imports. No globals, not even a window.$
for legacy parts. We avoid ProvidePlugin and expose-loader. If it’s webpack’d, it’s written as modular application code for import/export.
HMR for development. It’s an amazing productivity enhancer. Some browser issues to begin with, that are now ironed out by time. We start the webpack dev server from a foreman Procfile.
Components include scoped CSS. We use a fair bit of Vue, with only a smattering of global CSS to tie it together. Most styles are in Vue components.
All under app/javascript/. If it’s built by Webpacker, we keep it under there (unless it’s from packages). The name isn’t perfect, but it’s established as a single place to look.
Diff reduction. Configs should vary from “Webpacker default” in ways that ease merging of future updates. E.g. no structural changes, block insertions only.
Within app/javascript
we differ from Webpacker’s out-of-the-box samples and take an approach that feels more Rails-y, grouping source files by type and trying for connaissance of name wherever possible.
packs/:packname.js. Packs generally correspond to a layout in app/views/layouts
to minimise proliferation and complexity.
styles/:packname.scss. Global styles for a given pack, which activates them by import styles/packname.scss
in the js.
images/:packname/:image.png. Graphics assets for a given pack. Resolved as nonrelative paths e.g. background-image: url(~images/admin/brushed4.png)
, which writes the correct URLs for our CDN.
components/:component-name.vue. Vue components, namespaced by classification (not responsibility) when a flat directory gets unwieldy.
We’ve noted caching, FOUT, and compatibility issues with CSS-in-JS, so in production it’s extract_css: true
, precompiling all assets to CDN in the deploy pipeline, and referenced via stylesheet_pack_tag
and javascript_pack_tag
separately.
I reckon the only thing missing from Webpacker’s capabilities is a good story for engine assets. Webpack (and it’s ecosystem) is a powerful enabler, and I really would not willingly return to Sprockets today. However (with a nod to those of us who follow DHH’s other career), it’s like we’ve been given a LMP to drive, but the assembly instructions for a bicycle.
All this said, I would not be at all surprised if other folks had very different perspectives and practices. I can’t claim any of the above is a “best practice”, it’s all just a comfortable local maxima, discovered for ourselves.
I agree that an up to date Rails Guide on Webpacker would be a big help. Even if it just duplicated the Webpacker readme, it’d be easier to find in Rails Guides…
Also, at the risk of sounding self-promotional, and feel free to ignore, Modern Front End Development For Rails goes pretty in-depth on Webpacker. I haven’t caught up to 5.0 yet, though I will. I’ve even got a promo code that was meant for RailsConf, but will do fine for A May of WTFs: RailsConf_CouchEdition_2020
.
A vote from Twitter:
Sassc gives me a segfault when I try to use it (https://github.com/sass/sassc-ruby/issues/197) so switching completely to webpacker has been very helpful.