Skip to content

splitChunks splits chunks correctly, but all of them are always injected in <head>. Use case with dynamically imported polyfills not working #9862

@kyr0

Description

@kyr0

Bug report

What is the current behavior?

With the following configuration:

        splitChunks: {
            chunks: 'async',
            minSize: Infinity,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    chunks: 'all',
                    test: /[\\/]node_modules[\\/]/,
                    enforce: true,
                    // @ts-ignore
                    name(module, chunks, cacheGroupKey) {
                        let packageNameSplits = module.rawRequest.split('/');
                        let packageName: string = packageNameSplits[0];
                        if (module.rawRequest[0] === '@') {
                            packageName = packageNameSplits[0] + '/' + packageNameSplits[1];
                        }
                        return `${cacheGroupKey}.${packageName}`;
                    },
                    priority: -10,
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true,
                },
            },
        },

All chunks are correctly created.

However, they are all injected in the index.html for initial loading, including the ones that are imported via dynamic import import('...'). I would like to import the chunk only after a certain browser feature detection check says so at runtime.

Bildschirmfoto 2019-10-19 um 21 47 18

const polyfills = [];

setTimeout(() => {

    if (!window.fetch) {
        polyfills.push(import('whatwg-fetch'));
    }
    
    if (!window.Proxy) {
        polyfills.push(import('proxy-polyfill/src/proxy'));
    }

    Promise.all(polyfills)
        .then(() => {
            console.log('Polyfilly loaded!');
        })
        .catch(error => {
            console.error('Failed fetching polyfills', error);
        });
}, 1000);

I can use excludeChunks in HtmlWebpackPlugin to exclude these chunks like this:

excludeChunks: [ 'vendors.proxy-polyfill', 'vendors.whatwg-fetch' ]

However in this case, the main code is not executed anymore.

This behaviour doesn't allow me to implement the use-case to chunk and manually decide what polyfills to load dynamically via import() at runtime.

If the current behavior is a bug, please provide the steps to reproduce.

Just clone this repo and follow these instructions:

https://github.com/springtype-org/st-start#build-and-test

In __test__/fixture you can run yarn start:prod to create a prod build with chunks. The resulting dist/index.html can be opened in a browser to show the result described above.

If https://github.com/springtype-org/st-start/blob/master/src/function/getDefaultIndexHTMLConfig.ts#L23 is uncommented to exclude the polyfill chunks in order to load them dynamically at runtime, yarn build is executed and yarn start:prod in the __test__/fixture folder, the main chunk is not executed anymore as described.

What is the expected behavior?

To be able to exclude the chunks and still have the main chunk being executed. They are not logically dependent on each other code wise.

Other relevant information:
webpack version: 4.41.2
Node.js version: 12.8.1
Operating System: MacOS High Sierra 10.13.4
Additional tools: yarn 1.19.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions