How to visualize the size of your app bundle.

Nov 07, 2020☕ 3 min read

If you use Next for developing web applications, you probably are using a custom next.config.js file. This file allows custom advanced configurations on dev server and build phases.

For example, a simplified version of my next config (using MDX), would look like:

const withMDX = require('@next/mdx')({
  extension: /\.mdx?$/,
});

module.exports = withMDX({
  pageExtensions: ['js', 'jsx', 'md', 'mdx'],
});

Now, you can use Next Bundle Analyzer, or use cross-env with Next Bundle Analyzer to check the size of your dependencies, and it will produce a beautiful treemap of them.

application bundle treemap

The production bundle dependencies treemap of this site, at the moment of writing this article.

However, a lot of those tutorials tell you to just write something like:

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({});

What happens if you have more configurations? withTypescript, withSass... How do you make all of them work together in harmony?

The answer is, you have 2 options:

1. Just chain the configurations

If the configurations are simple enough, you can do something like this to chain them:

module.exports = withCSS(
  withTypescript(
    withSass({
      cssModules: true,
      webpack: (config) => {
        return config;
      },
    })
  )
);

However, depending on the plugins you might be using, this option can be problematic. Entering the second option (that I know so far, and the one I'm using).

2. Using next-compose-plugins.

If you're already worried about dependencies, adding an extra one might be a doubtful approach. However, this plugin might be worth it to configure different other plugins where each plugin has its own specific configuration.

So, the way I configured my Next config to use MDX and Next Bundle Analyzer at the same time is:

// MDX config
const withMDX = require('@next/mdx')({
  extension: /\.mdx?$/,
});

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

module.exports = withPlugins([
  [
    withMDX,
    {
      pageExtensions: ['js', 'jsx', 'md', 'mdx'],
    },
  ],
  [optimizedImages],
  [withBundleAnalyzer, {}],
]);

A simplified version of this would be:

// [plugin: function, configuration?: object, phases?: array]
withPlugins([...plugins], nextConfiguration);

You can see here that we're using our two plugins (withMDX and withBundleAnalyzer), and the nextConfiguration is optional so we're passing none.

Thanks to this, we can use all the configurations previously mentioned, and we have an optimized blog, with images inside each post folder, and bundle analyzer to stay informed of our modules sizes. I hope this article was useful!

See you on the next one!