<aside> πŸ§‘β€πŸŽ“ The critical request chain will update after removal of dispatchers chunk. Learn more how to identify it:

How to identify critical request chain?

</aside>

To inline dispatchers chunk, means to inline separate dispatchers into other chunks and avoid their grouped import. This is important, as coverage (how used the code in the chunk is) of dispatchers chunk is very low (bellow 10%).

Untitled

Removing dispatchers chunk will have the following effect:

Untitled

To achieve this effect, the following actions are required:

1. Create a new build configuration plugin

Create a next extension, declare a build configuration plugin inside. It is possible to use an exiting extension too. Follow these instructions:

How to build configuration plugins?

2. Create a Webpack loader to remove dispatchers

<aside> 🧠 Webpack comes pre-loaded with Magic Comments feature. It allows hinting Webpack how to name the chunk group and what strategy use to load it. It looks as follows:

import(
    /* webpackMode: "lazy", webpackChunkName: "dispatchers" */
    'Store/Cart/Cart.dispatcher'
);

</aside>

To inline dispatchers, remove webpackChunkName magic comment from all dispatchers imports and replace webpackMode from lazy to eager, this will force Webpack to inline the module into the same chunk, yet return promise (such that logic that utilizes an import is intact). To avoid doing it manually in code, let’s create a custom Webpack loader to execute this task.

Create a new file dispatchers.js along the build configuration plugin, with following content:

module.exports = (rawSource) => {
		// Inline all dispatchers
    const magicComments = [...source.matchAll(
        /\\/\\*\\s+(?:webpack[A-z]+:\\s*['"]\\w+['"]\\s*,?\\s+)+\\*\\//gm
    )];

    return magicComments.reduceRight((acc, match) => {
        const { index } = match;
        const [magicComment] = match;

        if (!/["']dispatchers["']/.test(magicComment)) {
            // skip all non-dispatchers
            return acc;
        }

        const newMagicComment = magicComment
            // vvv Makes module import in the same chunk
            .replace('lazy', 'eager')
            // vvv removes hard-coded cache group
            .replace(/,\\s*webpackChunkName:\\s*["']dispatchers["']\\s*/, '')
            .replace(/\\s*webpackChunkName:\\s*["']dispatchers["']\\s*,/, '');

        const stringArray = acc.split('');
        stringArray.splice(index, magicComment.length, newMagicComment);
        return stringArray.join('');
    }, source);
};

3. Register the newly created loader

To add a loader into a Webpack configuration, modify the build configuration plugin:

webpackConfig.module.rules.push({
  test: /\\.(tsx|jsx|ts|js)?$/,
  loader: require.resolve('./dispatchers'),
});

<aside> πŸŽ‰ This is how you inline dispatchers!

</aside>