Upgrade guide for moving a Rails app from Webpack 3 to Webpack 4

Webpacker is Rails' way of integrating Webpack, and version 4 has been released just a few days ago, allowing us to use Webpack 4.

I successfully upgraded an existing real-world Webpack 3 application. Below are notes on everything that I encountered.
Note that we prefer not using the Rails asset pipeline at all and serving all assets through Webpack for the sake of consistency.

Preparations

  • Remove version locks in Gemfile for webpacker
  • Remove version locks in package.json for webpack and webpack-dev-server
  • Install by calling bundle update webpacker and yarn upgrade

Update file contents

  • Work through the Webpacker 4 migration guide Archive

    • Run npx babel-upgrade --write which will download and run babel-upgrade Archive to auto-fix some config files (including some you may not need)
    • Place supported browsers (might live in .babelrc) into .browserslistrc in your project's root directory
    • Look at the default webpacker.yml Archive and merge any changes to your project's webpacker.yml. Add extract_css: true to the default section make sure CSS files are still built by Webpacker.
    • Replace .babelrc with babel.config.js. I suggest you take the default file Archive and compare it with your .babelrc plugins list and add missing ones. You may remove the environment switches in babel.config.js and function wrapper.
    • Replace .postcssrc with postcss.config.js. Use the default file Archive and add any missing plugins.
    • Webpacker 4 will transpile code inside node_modules. Apparently this could fix some issues but also cause others. Webpack 3 did not do that and if everything was fine before, maybe just restore the previous behavior Archive by adding environment.loaders.delete('nodeModules') to your environment.js.
    • If you used postcss-cssnext before, add it to your package.json (it's no longer provided by default).

      Info

      'postcss-cssnext' has been deprecated in favor of 'postcss-preset-env'.
      Read more at https://moox.io/blog/deprecating-cssnext/ Archive

  • Read through the Webpack 4 migration guide Archive

    • If your project previously fixed UglifyJs for IE 11 via uglifyOptions.ecma = 5, remove that line from your pack's production.js. Your .browserslistrc should define the required ECMAScript level implicitly.
  • Skim the Babel 7 migration guide Archive .

    • Babel 7 namespaced many packages.
      • You probably used import 'babel-polyfill' before. You now need to say this to avoid build errors like Module not found: Error: Can't resolve 'babel-polyfill' (see here Archive ):
        import "core-js/shim"; // included < Stage 4 proposals
        import "regenerator-runtime/runtime";
        
    • Note that options in configuration files may no longer be defined as comma-separated lists.
    • You might not need to change anything (aside from babel-polyfill) since babel-upgrade should have changed package names for you, and the default files also use Babel 7's package names.
    • If you are interested in all the new shiny features, check the Babel 7 release blog post Archive
  • Webpack 4 also namespaces files compiled files inside a pack

    • CSS files are stored inside css, JavaScripts inside js and images inside media
    • If you namespaced your pack's contents like <webpack-root>/your-pack-name/images (which was possible with Webpack 3) note that you can no longer do that because Webpacker's view helpers won't be able to locate files.
      • Basically all your assets should live in <webpack-root>, e.g. <webpack-root>/images.
      • If you want to namespace files, use <webpack-root>/images/your-pack-name.
      • Your pack manifest's import and require statements need to be adjusted accordingly.
      • If you have it, maybe get rid of a <webpack-root>/your-pack-name/index.js and move everything into the pack manifest at <webpack-root>/packs/your-pack-name.js.
    • Note that Webpacker provides more helpers to reach assets, like resolve_path_to_image. See Webpacker::Helper Archive .

Confirm everything works

  • If you're using it, start bin/webpack-dev-server to see if Webpack compiles properly.
  • Boot up rails server and check if your application responds and everything looks okay.
  • Run your application's tests.
Arne Hartherz about 3 years ago
This website uses short-lived cookies to improve usability.
Accept or learn more