Splitting Webpacker Alphabetically

A very, very odd way of splitting up your vendor libraries that worked for me.

Splitting Webpacker Alphabetically

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Late on a Friday night, I was running into the above error whilst deploying my app to Heroku.

I knew that the reason I was seeing this was that our final bundle was way too large. Sure, I could use webpack-bundle-analyzer plugin to see what my worst offending libraries were to remove them, but I was going on a train trip so didn't have time.

I needed to quickly deploy a bug fix and head out.

The route I took to quickly bypass the issue was to chunk libraries alphabetically. This took one big file and split it into (MAX) 26 smaller files that loaded very quickly over HTTP/2.

i.e react and react-dom would be in r.js and motion would be in m.js.

I placed the following in my environment.js file to make it work:

const { environment } = require('@rails/webpacker');
environment.loaders.delete('nodeModules');
environment.config.optimization = {
  runtimeChunk: 'single',
  splitChunks: {
    chunks: 'all',
    maxInitialRequests: Infinity,
    minSize: 0,
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name(module) {
          // get the name. E.g. node_modules/packageName/not/this/part.js
          // or node_modules/packageName
          const packageName = module.context.match(
            /[\\/]node_modules[\\/](.*?)([\\/]|$)/
          )[1];

          // npm package names are URL-safe, but some servers don't like @ symbols
          // additionally, we group alphabetically to ensure we don't have too many chunks which stops Amazon request issues
          return `npm.${packageName.replace('@', '')[0]}`;
        },
      },
    },
  },
};
environment.splitChunks();

module.exports = environment;

I haven't come back to optimise this yet, but I'm sure I can make it much better in the future.

Subscribe to my personal updates

Get emails from me about building software, marketing, and things I've learned building products on the web. Occasionally, a quiet announcement or two.

Email marketing powered by Bento