如何将 Webpack 4 SplitChunksPlugin 与 HtmlWebpackPlugin 一起用于多页面应用程序?
How to use Webpack 4 SplitChunksPlugin with HtmlWebpackPlugin for Multiple Page Application?
我正在尝试利用 SplitChunksPlugin 为 MPA 中的每个 page/template 生成单独的包。当我使用 HtmlWebpackPlugin 时,每个页面都有一个 html 文件,其中有一个指向正确包的脚本标记。太棒了!但是,我遇到的麻烦是我的供应商文件。我希望单独的 html 文件仅指向他们需要的供应商包。当 SplitChunksPlugin 创建多个供应商包时,我无法让每个单独的 html 文件指向正确的供应商包。产生的包是:
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,而不是第二个 vendor bundle。只有购物车和产品模板应该引用这两个供应商包。我正在使用 HtmlWebpackPlugin 的 chunks 选项,但无法让它提取正确的供应商包,除非我像这样明确引用它的名称:
chunks: ['vendors~cart~home~product.bundle','home']
但这有点违背了动态呈现脚本标签的目的。我试过创建一个供应商入口点,但这会将我所有的供应商混在一起。
是否缺少一些简单的配置?
我的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']
}),
], ...
我的 js 模块:
/* home.js */
import jQuery from 'jquery';
import 'bootstrap';
购物车和产品也引用了 React 库:
/* 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';
示例 html 输出 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>
一种选择是手动创建供应商块,然后在 HtmlWebpackPlugin
的 chunks
选项中包含页面所需的任何块。
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: {
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']
}),
], ...
vendor-all
块用于捕获未包含在其他块中的任何其他供应商库。
使用版本4的html-webpack-plugin(目前处于测试阶段),并且只在chunks选项中包含入口chunk。
npm i -D html-webpack-plugin@next
和
module.exports = {
new HtmlWebpackPlugin({
filename: 'home.html',
chunks: ['home']
}),
new HtmlWebpackPlugin({
filename: 'product.html',
chunks: ['product']
}),
new HtmlWebpackPlugin({
filename: 'cart.html',
chunks: ['cart']
}),
};
这将自动包含相关块。
我正在尝试利用 SplitChunksPlugin 为 MPA 中的每个 page/template 生成单独的包。当我使用 HtmlWebpackPlugin 时,每个页面都有一个 html 文件,其中有一个指向正确包的脚本标记。太棒了!但是,我遇到的麻烦是我的供应商文件。我希望单独的 html 文件仅指向他们需要的供应商包。当 SplitChunksPlugin 创建多个供应商包时,我无法让每个单独的 html 文件指向正确的供应商包。产生的包是:
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,而不是第二个 vendor bundle。只有购物车和产品模板应该引用这两个供应商包。我正在使用 HtmlWebpackPlugin 的 chunks 选项,但无法让它提取正确的供应商包,除非我像这样明确引用它的名称:
chunks: ['vendors~cart~home~product.bundle','home']
但这有点违背了动态呈现脚本标签的目的。我试过创建一个供应商入口点,但这会将我所有的供应商混在一起。 是否缺少一些简单的配置?
我的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']
}),
], ...
我的 js 模块:
/* home.js */
import jQuery from 'jquery';
import 'bootstrap';
购物车和产品也引用了 React 库:
/* 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';
示例 html 输出 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>
一种选择是手动创建供应商块,然后在 HtmlWebpackPlugin
的 chunks
选项中包含页面所需的任何块。
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: {
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']
}),
], ...
vendor-all
块用于捕获未包含在其他块中的任何其他供应商库。
使用版本4的html-webpack-plugin(目前处于测试阶段),并且只在chunks选项中包含入口chunk。
npm i -D html-webpack-plugin@next
和
module.exports = {
new HtmlWebpackPlugin({
filename: 'home.html',
chunks: ['home']
}),
new HtmlWebpackPlugin({
filename: 'product.html',
chunks: ['product']
}),
new HtmlWebpackPlugin({
filename: 'cart.html',
chunks: ['cart']
}),
};
这将自动包含相关块。