Reputation: 162
What's the best way to automate the generation of (or even manually figure out) the script tags to use for an entry point in a multi-entry webpack setup?
I'm setting up an MVC application to use webpack for an enormous number of javascript dependency libraries. Since the MVC app loads a new page for each route, I have dozens of entry points, each with its own entry script.
I'm using code splitting and hash-naming (for cache-busting).
Since webpack is working out the dependency tree for each entry point, it seems to be doing a great job of breaking out the code into bundles for reuse. Here's my config (minus the code at the top and the plugins):
module.exports = {
mode: "development",
entry: {
products_index: './Scripts/app/pages/Products/index.js',
users_index: './Scripts/app/pages/Users/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
},
node: {
fs: 'empty',
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like @ symbols
return `npm.${packageName.replace('@', '')}`;
},
},
},
},
},
I've limited the entries to 2 for this example, but I've got many more.
The output in dist
for this setup is:
index.html
npm.accounting.acb8cd33.js
npm.dropzone.1dcac339.js
npm.jquery.7fe2b020.js
npm.knockout-amd-helpers.356a8521.js
npm.knockout-punches.efb33702.js
npm.knockout.eaf67101.js
npm.knockout.mapping.e01549c3.js
npm.moment.0f7e6808.js
npm.sprintf-js.82f89700.js
npm.toastr.c6448676.js
npm.webpack.2aab6b7b.js
runtime.acfdeda3.js
products_index.8ef7831b.js
products_index~users_index.02e60e46.js
users_index.42c4b7af.js
This approach is convincingly presented here and seems logical so I've used it.
Everything seems to go swimmingly until I have to create the script tags for this monster.
On the /users
route, for example, how do I know which of these files to include? It seems webpack has done all this dependency mapping and left me to do it all again myself!
I can't find anything in in the Webpack documentation site that mentions how to best do this, except a discussion of the html-webpack-plugin which seems solely focused on creating one useless HTML file that just jams all the script tags into to a single file.
I must be missing something obvious here.
Upvotes: 3
Views: 3313
Reputation: 162
I finally came across an answer buried in a response to an issue on the html-webpack-plugin github site.
If you specify the entry point chunk to the plugin, it correctly calculates the dependencies from there, so you can create a loop in your webpack config that builds the entry
config and the plugin
config parts and then add them to your config, like this:
var entry: {
a: "./a",
b: "./b",
c: ["./c", "./d"]
};
var entryHtmlPlugins = Object.keys(entry).map(function(entryName) {
return new HtmlWebpackPlugin({
filename: entryName + '.html',
chunks: [entryName]
})
});
module.export = {
entry: entry,
//....
plugins: [
// ..
].concat(entryHtmlPlugins)
}
The issue page is here: https://github.com/jantimon/html-webpack-plugin/issues/299#issuecomment-216448896
At least in my preliminary testing, this seems to work. Would be great if it was mentioned somewhere in the docs.
Upvotes: 4