preface

Other public resources mainly have two users: first, the project is a multi-page application, there are multiple entries, there are modules and codes used in common between multiple pages. At this point, the common parts of multiple pages can be extracted. Second, we can extract the whole C-side project from the public code, so that users can load and cache public files when opening a page, and then open other pages, they can directly hit the cache of public files, reducing the download of resources.

How do I extract common code

There are two ways to extract common code. One is to use SplitChunksPlugin plug-in, and the other is to use the combination of DllPlugin and DllReferencePlugin.

Before and after Webpack3, CommonsChunkPlugin was used to extract common resources. After Webpack4, CommonsChunkPlugin was deleted and SplitChunksPlugin was used instead.

SplitChunksPlugin

If not configured, WebPack4 automatically uses splitChunks to split resource blocks. The default splitting rules are as follows:

  • The block is referenced multiple times or comes from the node_modules directory
  • Block size greater than 30KB (before compression)
  • The number of parallel requests for blocks loaded on demand cannot exceed 5
  • The number of parallel requests for initially-loaded blocks cannot be greater than 3

That is, splitChunks will only splitChunks that are referred to multiple times, or chunks that come from the node_modules directory; The size of the block must be greater than 30kb before compression. Otherwise, the block is not removed. At the same time, the last two conditions limit the number of parallel requests, which means that large blocks may be generated to satisfy the latter two conditions.

Custom Configuration

The splitChunksPlugin plug-in provides configuration parameters that allow developers to customize packages and split chunks.

module.exports = {
    / /...
    optimization: {
        splitChunks: {
            chunks: 'async'.// all Async initial selects which blocks to optimize
            minSize: 30000.// The minimum size to be split (before compression)
            minChunks: 1.// The minimum number of times to be shared
            maxAsyncRequests: 5.// Maximum number of concurrent requests on demand
            maxInitialRequests: 3.// Initialize the maximum number of parallel requests
            automaticNameDelimiter: '~'.// Automatically name delimiters
            name: true.// Automatically name the block
            cacheGroups: {
                vendor: { // Key is the entry name defined in entry
                    chunks: "initial"./ / must choose three: "initial" | | "all" "async" (the default is asynchronous)
                    test: /react|lodash/.// Verify the regular rule. If it matches, extract chunk
                    name: "vendor".// The name of the separated chunk to cache
                    minSize: 0.minChunks: 1.enforce: true.maxAsyncRequests: 1.// Maximum number of asynchronous requests. Default: 1
                    maxInitialRequests : 1.// Maximum initialization request, default 1
                    reuseExistingChunk: true // You can set whether to reuse the chunk.
                },
                default: {
                    minChunks: 2.priority: -20.reuseExistingChunk: true
                }
            }
        }
    }
}
Copy the code

DllPlugin

The DllPlugin configuration is more complex than splitChunksPlugin. The DLLPlugin and DLLReferencePlugin have somehow managed to break down bundles while greatly increasing the speed of builds.

DllPlugin needs to set up packaged configuration files and package third-party components prior to project packaging; The plugin creates a DLL – only bundle and generates manifest.json files to map the DllReferencePlugin to the dependencies.

The DllReferencePlugin, which is set up in the WebPack main configuration file, refers dlL-only bundles (s) to the required precompiled dependencies.

DLLS should only be used in the build environment, otherwise debugging will be problematic.

Configuration webpack. DLL. Config. Js

Configure webpack.dll.config.js first to package and generate common JS

const path = require('path')
const webpack = require('webpack')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
    mode: 'production'.devtool: false.entry: {
        react: [
            'react'.'react-dom'.'react-router-dom'.'prop-types'.'react-fastclick'.'classnames',].common: [
            'axios',]},output: {
        path: path.join(__dirname, '.. /dist'),
        filename: 'lib/[name]_[hash:4].dll.js'.library: '[name]_[hash:4]'
    },
    performance: {
        hints: false.maxAssetSize: 300000.// A command line alarm was generated when a single file exceeds 300 KB
        maxEntrypointSize: 300000.// The total number of files loaded for the first time exceeds 300K
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({ 
                parallel: true  // Enable multi-threaded parallelism}})],plugins: [
        new webpack.DllPlugin({
            context: __dirname,
            path: path.join(__dirname, '.. /dist/lib'.'[name]-manifest.json'),
            name: '[name]_[hash:4]'}})]Copy the code

Add commands to package.json

"scripts": {
    "dll": "webpack --config build/webpack.dll.config.js",}Copy the code

When we run the NPM run DLL command, we will package the public code or third party package of the configuration and generate the manifest.json file.

Running the NPM Run DLL produces the following code

Dist ├ ─ ─ lib │ ├ ─ ─ common - manifest. Json │ ├ ─ ─ common_cf4c. DLL. Js │ ├ ─ ─ the react - manifest. Json │ └ ─ ─ react_cf4c. DLL. JsCopy the code

Configuration webpack. Pro. Config. Js

After the DLL file is generated, you can configure the webpack.pro.config.js file, in addition to the need to use the DllReferencePlugin to map DLL libraries, We also need to use the HTMl-webpack-include-assets-plugin to insert the common JS library into the HTML.

Webpack.pro.config.js configuration:

const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin')
// ...
plugins: [
    new webpack.DllReferencePlugin({
        context: __dirname,
        manifest: require('.. /dist/lib/react-manifest.json')}),new webpack.DllReferencePlugin({
        context: __dirname,
        manifest: require('.. /dist/lib/common-manifest.json')}),new HtmlWebpackIncludeAssetsPlugin({
        assets: [{ path: 'lib'.glob: '*.dll.js'.globPath: 'dist/lib/'}].append: false})]Copy the code

Package. The json configuration

"build": "cross-env NODE_ENV=production node ./build/build.js".Copy the code

The online package can be packaged by running NPM Run build, because the DLL library is packaged in advance and the online package is packaged later.