By default, ScandiPWA plugin system (Mosaic) injects all plugins into the application entry-point.

<aside> 🧠 An entry-point (src/index.js) is a part of main bundle (the first chunk loaded on page).

The main bundle, originally, contains only the code necessary for rendering Router component. Routes (and components before and after them, like Header and Footer) are lazy-loaded, therefore keeping them away from the main bundle.

The critical rendering path of each element (on any page) in the application includes the entry-point, App, and Router component. This means, increasing the main bundle size (by importing something without lazy in the Router, App or an entry-point) will result in delays displaying the critical element.

</aside>

With previous architecture, the more plugins application had, the larger the main bundle size was. As most features are shipped through extensions (which are using plugins) this is a significant problem on real projects.

To overcome this problem, ideally, the plugins should be loaded just before they are used, for example, the plugin for Route/Checkout/Component should only be loaded when Checkout component is rendered.

This is exactly what we aimed to implement in release 1.0.0 of Mosaic. The plugins will now be loaded dynamically, directly before they are used. Here is how to install it:

1. Update mosaic in the root package

From ScandiPWA application root, run install versions of Mosaic and ScandiPWA scripts:

yarn add @tilework/mosaic@latest @tilework/mosaic-craco@latest @scandipwa/scandipwa-scripts@latest # for Yarn
npm i @tilework/mosaic@latest @tilework/mosaic-craco@latest @scandipwa/scandipwa-scripts@latest # for NPM

2. Update plugin declarations

New version of mosaic, only allows plugin configuration directly from export default. For example, the following configuration is NOT ALLOWED:

export const config = {
    'Component/Header/Component': {
        'member-property': {
            stateMap: aroundStateMap
        }
    }
};

export default config;

Instead, the code above should be converted to:

export default {
    'Component/Header/Component': {
        'member-property': {
            stateMap: aroundStateMap
        }
    }
};

<aside> 💡 In VSCode for fast replacement of exporting plugin configurations, next regex can be used: search - export const config = \\{(\\n[\\s\\S\\n]+?)\\};\\n?\\nexport default config; replace - export default {$1};

</aside>

3. Validate installation

To validate if dynamic plugins are working, search the build directory to contain addPlugins function call in multiple chunks.