javascript - splitchunks - webpack doc_page src app page body body share_this_document
¿Cómo usar Webpack 4 SplitChunksPlugin con HtmlWebpackPlugin para aplicaciones de múltiples páginas? (2)
Una opción es crear manualmente los fragmentos de su proveedor y luego incluir cualquiera de esos fragmentos necesarios para una página en la opción de chunks
de HtmlWebpackPlugin
.
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'']
}),
], ...
El trozo vendor-all
es para capturar cualquier otra biblioteca de proveedores que no esté incluida en los otros trozos.
Estoy tratando de utilizar el SplitChunksPlugin para producir paquetes separados para cada página / plantilla en un MPA. Cuando uso HtmlWebpackPlugin, obtengo un archivo html para cada página con una etiqueta de script que apunta al paquete correcto. ¡Eso es genial! Sin embargo, el problema que tengo es con los archivos de mis proveedores. Quiero que los archivos html separados apunten solo a los paquetes de proveedores que necesitan. No puedo conseguir que cada archivo html separado apunte a los paquetes de proveedores correctos cuando SplitChunksPlugin crea varios paquetes de proveedores. Los paquetes producidos son:
home.bundle.js
product.bundle.js
cart.bundle.js
vendors~cart~home~product.bundle.js
vendors~cart~product.bundle.js
Básicamente, la plantilla de inicio debe hacer referencia a home.bundle.js, vendors ~ cart ~ home ~ product.bundle.js, y no al segundo paquete de proveedores. Solo las plantillas de carrito y producto deben hacer referencia a ambos paquetes de proveedores. Estoy utilizando la opción de fragmentos para HtmlWebpackPlugin, pero no puedo hacer que obtenga los paquetes de proveedores correctos a menos que haga referencia explícita al nombre de esta manera:
chunks: [''vendors~cart~home~product.bundle'',''home'']
Pero esto no sirve para representar dinámicamente las etiquetas de su script. He intentado crear un punto de entrada de proveedor, pero esto agrupa a todos mis proveedores. ¿Hay alguna configuración simple que me falta?
Mi 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'']
}),
], ...
Mis módulos js:
/* home.js */
import jQuery from ''jquery'';
import ''bootstrap'';
El carrito y el producto también hacen referencia a la biblioteca de reacción:
/* 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'';
Ejemplo de salida 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>
Use la versión 4 de html-webpack-plugin (que ahora está en versión beta), e incluya solo el fragmento de entrada en la opción de fragmentos.
npm i -D html-webpack-plugin@next
y
module.exports = {
new HtmlWebpackPlugin({
filename: ''home.html'',
chunks: [''home'']
}),
new HtmlWebpackPlugin({
filename: ''product.html'',
chunks: [''product'']
}),
new HtmlWebpackPlugin({
filename: ''cart.html'',
chunks: [''cart'']
}),
};
Esto incluirá trozos relacionados automáticamente.