Bald
Bald

Reputation: 2316

Why does webpack ignore chunk in production mode?

I have multiple entry points that share same code. What I need to do is to extract this code into one file using splitCode in webpack 4. This works fine in development mode but not in production.

Configuration file:

var path = require('path');
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const WebpackMd5Hash = require("webpack-md5-hash");
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    mode: "development",
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {

                    loader: 'babel-loader',
                }
            },
            {
                test: /\.(sass|scss|css)$/,
                use: [
                    "style-loader",
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "sass-loader"
                ]
            }
        ],
    },
    output: {
        path: path.join(__dirname, 'public'),
        filename: 'js/[name]-[chunkhash].js',
        chunkFilename: 'js/[name]-[chunkhash].js',
        publicPath: '/'
    },
    externals: {
        jquery: "jQuery"
    },
    optimization: {
        runtimeChunk: "single",
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendor",
                    chunks: "all",
                    priority: 1
                },
                utilities: {
                    test: /\.s?js$/,
                    minChunks: 2,
                    name: "utilities",
                    chunks: "all",
                    priority: 0
                }
            }
        }
    },
    context: path.join(__dirname, 'resources/assets'),
    entry: {
        a: './js/a.js',
        b: './js/b.js'
    },
    plugins: [
        new CleanWebpackPlugin(['public/js/*.*', 'public/css/*.*'], {} ),

        new MiniCssExtractPlugin({
            filename: "css/[name]-[contenthash].css"
        }),

        new WebpackMd5Hash(),

        new ManifestPlugin({
            fileName: 'manifest.json'
        }),
    ]
};

In development mode Webpack creates two entry points, one runtime.js, vendor.js and utilities.js which is ok.

When I change mode from development to production, webpack ignores utilities cacheGroups and appends common codebase into two entry points.

What am I missing?

Webpack version: 4.28.4 Node version: 8.15

Upvotes: 4

Views: 2639

Answers (4)

S. Esteves
S. Esteves

Reputation: 453

Webpack SplitChunksPlugin, by default, ignores any chunk smaller than 30kb. If you run Webpack in development mode, you'll be able to see the bundle size of utilities.js and enforce the split by setting optimization.splitChunks.minSize option smaller than the size of utilities.js.

Upvotes: 0

Jake
Jake

Reputation: 254

It's not a bug. It's a feature

Webpack 4 splitchunks.cacheGroups is ignored in production mode IF the new chunk is less than the size of 30kb.

solution to override this default condition:

user splitchunks.cacheGroups.runtime.enforce: true if you want to really make sure that these chunks are created

Check the documention for further details https://webpack.js.org/plugins/split-chunks-plugin/#defaults

Upvotes: 2

Bald
Bald

Reputation: 2316

It seems like setting enforce to true does the job (but I'm not entirely really sure why).

It should be like this:

utilities: {
    test: /\.s?js$/,
    minChunks: 2,
    name: "utilities",
    chunks: "all",
    priority: 0,
    enforce: true
}

From now on, utilities.js is being created not only in development mode, but also in production.

Upvotes: 3

BisonAVC
BisonAVC

Reputation: 2096

Specifying minChunks: 2 means it will only create a split bundle if the given common imports is specified in at least 2 modules. You might want to verify but dropping it to 1.

There are few additional default rules listed here: https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693#defaults but mainly if the common codebase isn't larger than 30kb (before min+gz) then it won't get split out. You can force it by updated the key minSize as listed in the default optimization config.

Upvotes: 1

Related Questions