Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm trying to utilize the SplitChunksPlugin to produce separate bundles per each page/template in a MPA. When I use the HtmlWebpackPlugin, I get an html file for each page with a script tag pointing to the correct bundle. That is great! However, the trouble I'm having is with my vendor files. I want separate html files to point to only the vendor bundles they need. I can't get each separate html file to point to the correct vendor bundles when the SplitChunksPlugin creates multiple vendor bundles. The bundles produced are:

home.bundle.js product.bundle.js cart.bundle.js vendors~cart~home~product.bundle.js vendors~cart~product.bundle.js 

So basically the home template should reference home.bundle.js, vendors~cart~home~product.bundle.js, and not the second vendor bundle. Only the cart and product templates should reference both vendor bundles. I am utilizing the chunks option for the HtmlWebpackPlugin but can't get it to pull the correct vendor bundles unless I explicitly reference the name of it like so:

chunks: ['vendors~cart~home~product.bundle','home'] 

But this kinda defeats the purpose of dynamically rendering your script tags. I've tried creating a vendor entry point but this lumps all my vendors together. Is there some simple config I'm missing?

My webpack.config.js:

const path = require('path'); const webpack = require('webpack'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const Visualizer = require('webpack-visualizer-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');  module.exports = {     mode: 'development',     devtool: 'cheap-module-eval-source-map',     entry: {         home: './src/js/page-types/home.js',         product: './src/js/page-types/product.js',         cart: './src/js/page-types/cart.js'     },     output: {         filename: '[name].bundle.js',         path: path.resolve(__dirname, 'dist/js')     },     optimization: {         splitChunks: {             chunks: 'all'         }     },     plugins: [         new CleanWebpackPlugin(['dist']),         new Visualizer(),         new HtmlWebpackPlugin({             filename: 'home.html',             chunks: ['vendors','home']         }),         new HtmlWebpackPlugin({             filename: 'product.html',             chunks: ['vendors','product']         }),         new HtmlWebpackPlugin({             filename: 'cart.html',             chunks: ['vendors~cart~product','cart']         }),     ], ... 

My js modules:

/* home.js */     import jQuery from 'jquery';     import 'bootstrap'; 

cart and product also reference the react library:

/* cart.js */     import jQuery from 'jquery';     import 'bootstrap';     import React from 'react';     import ReactDOM from 'react-dom'; 

 

/* product.js */     import jQuery from 'jquery';     import 'bootstrap';     import React from 'react';     import ReactDOM from 'react-dom'; 

Example html output home.html:

<!DOCTYPE html> <html>   <head>     <meta charset="UTF-8">     <title>Webpack App</title>   </head>   <body>   <script type="text/javascript" src="home.bundle.js"></script></body> </html> 
like image 226
Dave Avatar asked Jun 11 '18 17:06

Dave


People also ask

What is the use of HtmlWebpackPlugin?

The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation.

How do I bundle files in webpack?

You can bundle your JavaScript using the CLI command by providing an entry file and output path. Webpack will automatically resolve all dependencies from import and require and bundle them into a single output together with your app's script. But that's just the bare minimum it can do.

What is split chunks in webpack?

splitChunks.If the current chunk contains modules already split out from the main bundle, it will be reused instead of a new one being generated. This can affect the resulting file name of the chunk. webpack.config.js module.

Does webpack generate HTML?

Use webpack to build your JS assets and it will create a . html file with all assets imported in. Run yarn dev , and hopefully after a few sections you will see a dist directory was created with your JS files included.


1 Answers

Use version4 of html-webpack-plugin (which is in beta now), and only include the entry chunk in the chunks option.

npm i -D html-webpack-plugin@next 

and

module.exports = {     new HtmlWebpackPlugin({         filename: 'home.html',         chunks: ['home']     }),     new HtmlWebpackPlugin({         filename: 'product.html',         chunks: ['product']     }),     new HtmlWebpackPlugin({         filename: 'cart.html',         chunks: ['cart']     }), }; 

This will include related chunks automatically.

like image 187
nilptr Avatar answered Oct 02 '22 13:10

nilptr