I would like to set up a webpack 4 configuration for production which is using html-webpack-plugin to create multiple html files. In the same time, I would like to extract my vendor libs as separate chuncks, and manually set up which html file uses which vendor chunk by the using html-webpack-plugin.
I just started the project so at the moment my only vendor lib is vue.js, but over time this will grow.
What I want to achieve with the following configuration is just to have vue js as a single vendor lib included to all html files where I specify: chunks: ['vendor'] in the HtmlWebpackPlugin.
Unfortunately my vendors bundle is included only to the first html file, and after that it is ignored.
I also found out, that i can not control the inclusion of the vendor lib the following way: chunks: ['vendor','app']. 'vendor' is just ignored, probably because it only check what is in the entry configuration.
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const MinifyPlugin = require("babel-minify-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
module.exports = function (env, argv) {
return {
mode: 'production',
entry: {
vendor: ['vue'],
app: './src/js/app/app.js',
appCompose: './src/js/app/app-compose.js',
},
output: {
path: path.resolve(__dirname, "target/dist"), // string
filename: '[name].[contenthash:8].bundle.js'
},
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin(),
new UglifyJsPlugin({
test: /\.js(\?.*)?$/i,
exclude: /(node_modules)/,
cache: false,
parallel: true,
sourceMap: true,
extractComments: true
})
],
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
enforce: true
},
}
},
},
plugins: [
new CleanWebpackPlugin(['target']),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new MinifyPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new HtmlWebpackPlugin({
template: './src/pages/index/index.html',
filename: path.resolve(__dirname, 'target/index.html'),
chunksSortMode: "manual",
chunks: ['vendor','app'],
}),
new HtmlWebpackPlugin({
template: './src/pages/compose/index.html',
filename: path.resolve(__dirname, 'target/compose.html'),
chunksSortMode: "manual",
chunks: ['vendor','appCompose'],
}),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
},
{
test: /\.m?js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
};
The expected behaviour here, is that every html file receives the vendors and its own bundle from the output. What actually happens, is that only the first html file gets the vendors.
It would be great to be able to configure a page like that: chunks: ['vue','loadash','appCompose') and the the html-webpack-plugin injects them to the file.