如何将Webpack 4 SplitChunksPlugin与HtmlWebpackPlugin一起用于多页应用程序?

时间:2018-06-11 17:35:35

标签: javascript webpack build-tools html-webpack-plugin webpack-4

我正在尝试利用SplitChunksPlugin为MPA中的每个页面/模板生成单独的包。当我使用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,vendor~cart~home~product.bundle.js,而不是第二个供应商包。只有购物车和产品模板才能引用两个供应商包。我正在利用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';

购物车和产品也参考反应库:

/* 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>

2 个答案:

答案 0 :(得分:6)

使用html-webpack-plugin的version4(现在处于beta版),并且仅在“ chunks”选项中包括条目块。

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']
    }),
};

这将自动包括相关的块。

答案 1 :(得分:2)

一种选择是手动创建您的供应商块,然后在chunks的{​​{1}}选项中包含页面所需的任何块。

webpack.config.js:

HtmlWebpackPlugin

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'] }), ], ... 块将捕获其他块中未包括的任何其他供应商库。