How to use Webpack 4 SplitChunksPlugin with HtmlWebpackPlugin for Multiple Page Application?
我正在尝试利用SplitChunksPlugin在MPA中的每个页面/模板上生成单独的包。当我使用HtmlWebpackPlugin时,我会为每个页面获取一个html文件,并带有指向正确捆绑软件的脚本标签。这太棒了!但是,我遇到的麻烦是我的供应商文件。我希望单独的html文件仅指向他们需要的供应商捆绑包。当SplitChunksPlugin创建多个供应商捆绑包时,我无法获得每个单独的html文件来指向正确的供应商捆绑包。产生的束是:
1 2 3 4 5 | home.bundle.js product.bundle.js cart.bundle.js vendors~cart~home~product.bundle.js vendors~cart~product.bundle.js |
因此,基本上,主页模板应引用home.bundle.js,vendors?cart?home?product.bundle.js,而不是第二个捆绑销售商。仅购物车和产品模板应同时引用两个供应商捆绑包。我正在使用HtmlWebpackPlugin的chunks选项,但是除非我明确引用它的名称,否则无法获取正确的供应商捆绑包,如下所示:
1 | chunks: ['vendors~cart~home~product.bundle','home'] |
但这有点违反了动态呈现脚本标签的目的。我曾尝试创建一个供应商入口点,但这将我所有的供应商混为一谈。
我缺少一些简单的配置吗?
我的webpack.config.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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'] }), ], ... |
我的js模块:
1 2 3 | /* home.js */ import jQuery from 'jquery'; import 'bootstrap'; |
购物车和产品还引用了反应库:
1 2 3 4 5 | /* cart.js */ import jQuery from 'jquery'; import 'bootstrap'; import React from 'react'; import ReactDOM from 'react-dom'; |
1 2 3 4 5 | /* product.js */ import jQuery from 'jquery'; import 'bootstrap'; import React from 'react'; import ReactDOM from 'react-dom'; |
示例html输出home.html:
1 2 3 4 5 6 7 8 9 | <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> Webpack App </head> <body> <script type="text/javascript" src="home.bundle.js"></body> </html> |
使用html-webpack-plugin的version4(现在处于beta版),并且仅在块选项中包括条目块。
1 | npm i -D html-webpack-plugin@next |
和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | module.exports = { new HtmlWebpackPlugin({ filename: 'home.html', chunks: ['home'] }), new HtmlWebpackPlugin({ filename: 'product.html', chunks: ['product'] }), new HtmlWebpackPlugin({ filename: 'cart.html', chunks: ['cart'] }), }; |
这将自动包括相关的块。
一个选项是手动创建您的供应商块,然后在
webpack.config.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 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: { cacheGroups: { 'vendor-bootstrap': { name: 'vendor-bootstrap', test: /[\\\\/]node_modules[\\\\/](jquery|bootstrap)[\\\\/]/, chunks: 'initial', priority: 2 }, 'vendor-react': { name: 'vendor-react', test: /[\\\\/]node_modules[\\\\/]react.*?[\\\\/]/, chunks: 'initial', priority: 2 }, 'vendor-all': { name: 'vendor-all', test: /[\\\\/]node_modules[\\\\/]/, chunks: 'initial', priority: 1 }, } } }, plugins: [ new CleanWebpackPlugin(['dist']), new Visualizer(), new HtmlWebpackPlugin({ filename: 'home.html', chunks: ['vendor-bootstrap', 'vendor-all', 'home'] }), new HtmlWebpackPlugin({ filename: 'product.html', chunks: ['vendor-bootstrap', 'vendor-react', 'vendor-all', 'product'] }), new HtmlWebpackPlugin({ filename: 'cart.html', chunks: ['vendor-bootstrap', 'vendor-react', 'vendor-all', 'cart'] }), ], ... |