shakacode/shakapacker

shackpacker should manage its own dependencies

Closed this issue · 3 comments

Desired behavior:

Looking at https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/package.json, you'll see that this sample project has dependencies like "css-minimizer-webpack-plugin".

I have the same dependencies in my Shakapacker v6 project.

Often upgrading these packages is very problematic. Small bugs might exist in individual versions. There may be incompatibilities between related packages. And now when upgrading shakapacker I'm faced with updating this packages manually when I'm not using them directly.

If shakapacker is in charge of building the frontend assets, shouldn't it include these packages in its own package.json?

Setup environment:

  • Ruby version:
  • Rails version:
  • Shakapacker version:

Shakapacker is more focused on making it easy to integrate webpack with the Rails build pipeline and by extension it provides sensible webpack configs for common technologies like TypeScript and React, than trying to be a single monolithic opaque builder for your frontend assets.

One of the reasons for this is that historically such builders tend to bring in a lot of dependencies at specific versions just to support specific features that are not used by everyone but everyone consuming these builders still have to drag those (often sizable) dependencies around; beyond just having to install these dependencies everywhere, they often result in a lot of unpatchable security advisories which eat up maintainer time and cause pain for folks like me dealing with apps in high security environments where we can't just ignore an advisory forever - and then to top it off, they get abandoned, and then you're stuck with a huge migration to eventually tackle...

(create-react-app is a great case-and-point for this)

So instead of being that big monolith, Shakapacker tries to find a balance which comes at the cost of needing a bit more engagement from downstream consumers.

For example, we support including css-minimizer-webpack-plugin in the config if it's installed:

const tryCssMinimizer = () => {
if (
moduleExists('css-loader') &&
moduleExists('css-minimizer-webpack-plugin')
) {
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
return new CssMinimizerPlugin()
}
return null
}

There's no real downside to this because:

  • if you don't want it, you don't install it
  • if you do install it, then you must want it so we might as well add it (to the config) for you
  • if you want to fine tweak it, you can do so using the config/webpack/webpack.config.js

Generally all of our required major dependencies should be well declared - ones like Babel should be a peer dependency because you should have the same version across the dependency tree, which means you do have to explicitly specify them in your package.json if your manager doesn't support automatically installing peer dependencies (which npm and pnpm do, but yarn does not).

There's a couple that I think we could probably just make standard dependencies which I'm going to review as part of our upcoming v8, and we should really mark our optional dependencies in our package.json too which'll make it easier to know which you can remove but overall I don't think there's a lot that should be changed.

Think @G-Rath said everything here - Shakapacker main goal is effectively easy integration of webpack into Rails apps. The shipped config is a nice extra "just works" bit that one can enhance with installing specific packages but one can roll out their own config from scratch also.

Ultimately the build dependencies are really responsibility of the app and not Shakapacker so the current solution feels like best of both worlds.

Closing as per discussion above