I have 3 pages.
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()
]
};