0

I have 3 pages.

Here is my dir structure.

Page1&page2 rely on vue, page2&page3 rely on jquery.So I use SplitChunksPlugin to separate chunks from page bundles.

But the problem comes with using html-webpack-plugin.Each page html must include js needed both main.bundle.js and common chunk js(eg.page1~page2.js),so I must get commonChunk names to filter.I can only get that info from the name function,but it is async. So how can I generate my HtmlWebpackPlugin obj, after the name callback is over...

Here is my webpack config.

const pageDir = './page';
const indexPage = 'page1';

const pages = fs.readdirSync(pageDir);
console.log('__dirname', __dirname);

let splitChunksName = [];

const getPagesHtmlWebpackPluginList = () => {
    console.log('splitChunksName',splitChunksName); // log [], expect after get splitChunksName to call
    return pages.map( page => {
        let regex = new RegExp(page);
        let commonChunks = splitChunksName.filter(name => regex.test(name));

        return new HtmlWebpackPlugin({
            filename: `${page}/index.html`,
           chunks: [`${page}/main`, ...commonChunks],
        });
    });
};

const getEntryObj = () => {
    let entry = {};
    pages.forEach(page => {
        Object.assign(entry, {
            [`${page}/main`]: [path.resolve(process.cwd(), pageDir, `./${page}/main.js`)]
        })
    });
    return entry;
};

module.exports = {
        mode: 'none',
        entry: getEntryObj(),
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: '[name].bundle.js'
        },
        optimization: {
            splitChunks: {
                chunks: 'all',
                name: module => {
                    // set 'name:true' the output dir becomes ugly, if chunk1 names 'a/b', chunk2 names 'c/d',
                    //then the common chunk12 will be 'venders~a/b~c/d.bundle.js', two ugly folders(venders~a , b~c)generated.
                    //So I write my own name function.
                    let arr = [];
                    module._chunks.forEach(chunk => {
                        arr.push(chunk.name.replace('/main',''));
                    });
                    let splitChunkName = 'vender/' + arr.join('~');
                    splitChunksName.push(splitChunkName);
                    //splitChunksName is needed,I need common chunk info to use with html-webpack-plugin
                    return splitChunkName;
                }

            }
        },
        plugins: [
            ...getPagesHtmlWebpackPluginList()
        ]
};
Null Nobody
  • 96
  • 1
  • 8

1 Answers1

0

As of html-webpack-plugin version 4, this is now supported natively.

How to use Webpack 4 SplitChunksPlugin with HtmlWebpackPlugin for Multiple Page Application?

firetiger77
  • 351
  • 3
  • 9