To achieve webPack packaging optimization, there are two optimization points:

  • How to reduce packing time

  • How to reduce package size

Reduce packing time

Optimize the Loader

For Loader, the first optimization is Babel, which converts code into strings and generates an AST, and then continues to convert it into new code. The more code is converted, the less efficient it becomes. First, you can optimize the search scope of Loader.

module.exports = {
    module: {
        rules: [
            test: /\.js$/.// Use Babel for js files
            loader: 'babel-loader'.include: [resolve('src')].// Only look in the SRC folder
            // The code in node_modules is compiled so it doesn't need to be processed again
            exclude: /node_modules/]}}Copy the code

You can also cache Babel compiled files to speed up packaging time, primarily by setting up cacheDirectory.

HappyPack

HappyPack can be used to parallelize Loader’s synchronous execution, thus executing Loader’s compile wait time.

module: {
    loaders: [
        test: /\.js$/,
        include: [resolve('src')].exclude: /node_modules/,
        loader: 'happypack/loader? id=happybabel' //id Id of the plug-in]},plugins: [
    new HappyPack({
        id: 'happybabel'.loaders: ['babel-loader? cacheDirectory'].threads: 4.// The number of threads opened})]Copy the code

DllPlugin

The plug-in can package specific libraries in advance and then bring them in, which greatly reduces the number of times the libraries are packaged, repackaged only when newer versions of the libraries are available, and optimizes the separation of common code into separate files.

// webpack.dll.conf.jsconst path = require('path')
const webpack = require('webpack')
module.exports = {
    entry: {
        vendor: ['react'] // The class library needs to be packaged uniformly},output: {
      path: path.join(__dirname, 'dist'),
        filename: '[name].dll.js'.library: '[name]-[hash]'
    },
    plugins: [
        new webpack.DllPlugin({
            name: '[name]-[hash]'.// Name must be the same as output.library
            context: __dirname, // Note that the context matches the DllReferencePlugin context
            path: path.join(__dirname, 'dist'.'[name]-manifest.json')]}})Copy the code

Then add a script to the package.json file

package.json

{'dll': 'webpack --config webpack.dll.js --mode=development' }
// The react.dll. Js and manifest.json dependencies are packaged
Copy the code

Finally, use the DllReferencePlugin to introduce the newly generated dependency files into the project

// webpack.conf.js
module.exports = {
    / /... Other configuration
    plugins: [
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require('./dist/vendor-manifest.json') // This is the packaged JSON file}})]Copy the code

For more information on how to configure DllPlugin in WebPack, see How to Use DllPlugin in WebPack and how to use DllPlugin in WebPack

Code compression correlation

  • In Webpack3, you can use UglifyJS compression code, but it is single-threaded, so you can use the webpack-parallel-Uglify-plugin to run UglifyJS. This configuration is enabled by default in webpack4 whenever mode production is enabled

  • Compress HTML and CSS code and configure to remove console.log and debugger to prevent possible memory leaks

new UglifyJsPlugin({
    UglifyOptions: {
        compress: {
            warnings: false.drop_console: true.pure_funcs: ['console.log']}},sourceMap: config.build.productionSourceMap,
    parallel: true
})
// Or use the following configuration
new webpack.optimize.UglifyJsPlugin({
    compress: {
        warnings: false.drop_debugger: true.drop_console: true}})Copy the code

Reduce package size

According to the need to load

The smaller the home page load file is, the better. Pack each page into a separate file (loading on demand is also available for the Loadsh library). The principle is to download the corresponding file at the time of use, return a promise, and execute the callback when the promise is successful.

Scope Hoisting

It will analyze the relationship between modules and combine the packaged modules into a function as much as possible

    // The test.js file is referenced in the index.js query
    export const a = 1  // test.js
    import {a} from './test.js'  // index.js
    // The package above will have two functions, similar to the following
    [
        function(module.exports.require) {} / / * * * * 0
        function(module.exports.require) {} / / * * 1 * *
    ]
Copy the code

In WebPack 4, simply enable concatenateModules.

module.exports = {
    optimize: {
        concatenateModules: true}}Copy the code

Tree shaking

It removes unreferenced code from the project, which is automatically enabled in WebPack 4 if you just start production