Webpack4.x has been out for some time, there are a lot of webpack 4.x principles and new features introduced on the web, such as zero configuration, etc., here will not repeat.

Recently upgraded a multi-page project previously written based on Webpack3.x to 4.x, documenting and summarizing the problems and solutions encountered in upgrading Webpack3.x to 4.x.

Project preview GIF:

webpack.czero.cn

In addition to differentiating 3.x and 4.x, the Webpack construction is optimized, and the basic configuration files of Webpack3.x and Webpack4.x are respectively configured to be hosted on Github, which can be used in the project to reduce the configuration time.

Webpack3.x:github.com/czero1995/w…

Webpack4.x:github.com/czero1995/w…

Webpack functions in the project:

  • Multi-page entry configuration
  • Componentization using Ejs templates (sharing headers and bottoms)
  • Extract public CSS files
  • Use HappyPack to do multithreaded packaging
  • The latest Babel compiler can compile ES7,ES8(decorator @, etc.)
  • DevServer, save automatic refresh
  • Introducing Less processors
  • Configuration TypeScript
  • Each Build deletes the files from the original Build

Distinguish between development and production environments

Development environment: NPM run dev Production environment: NPM run buildCopy the code

Differentiating development environments can improve Webpack packaging efficiency, for example

  • In the development environment:

    Configure debug mode devtool: cheap-source-map

    Configuring devServer: Save automatic refresh

  • Production environment:

    Configure debug mode devtool: inline-source-map

    Load and extract CSS components

    Load PostCss plugin (browser prefix for compatibility)

    Before adding a Build, delete the previous Build file

    The compression code

    Clear code comments and Spaces

    Load the PostCss plug-in

Several obvious differences and issues between Webpack3.x and Webpack4.x

1. Add parameters to run Webpack

Starting with 4.0: WebPack must be run with parameters

–mode development or –mode production,

Corresponding to the development environment and production environment, otherwise a warning will be reported:

3.x (package.json)

"scripts": {
    "build": "webpack --optimize-minimize",
    "dev": "webpack-dev-server --config webpack.dev.config.js"
  },
Copy the code

4.x (package.json)

"scripts": {
    "build": "webpack --optimize-minimize --mode production",
    "dev": "webpack-dev-server --config webpack.dev.config.js --mode development"
  },
Copy the code

2. To remove loaders, use rules

In Webpack3.x, loaders from the previous version can be used together with rules. In the new version, loaders are removed completely and rules must be used. Otherwise, an error will be reported. Change the loaders under module to rules

3. Install WebPack-CLI

4. X needs to install Webpack-CLI, otherwise it will not run

npm install webpack-cli --save
Copy the code

4. The TypeScript TS-Loader version is too early

In Webpack3. x, typescript works well. After upgrading to Webpack4. x, typescript can no longer be used because the version is too low. Or delete it and run NPM install TS-loader again

5. Ejs cannot be used

Webpack in combination with Ejs enables component-based development, sharing HTML code, such as headers and bottoms of multiple pages, component-led development and maintenance behind aspects.

4. X will report ejsRenderLoder of undefined. Htmlplugin configuration needs to be modified. 3. X is:

template: 'ejs-render-loader! pages/index.ejs',Copy the code

4. To x

template: 'ejs-loader! pages/index.ejs',Copy the code

5. The text-webpack-plugin version is too low, causing construction failure

Change the extract-text-webpack-plugin version number in package.json

"Extract - text - webpack - plugin" : "^ v4.0.0 - alpha. 0".Copy the code

Webpack build optimization

Distinguish between development and production environments

  • The development environment does not need to compress the code
  • Specify debug mode devtool mode

The compressed code uses ParalleUglifyPlugin instead of UglifyJsPlugin plug-in

Js compression plug-in is a single thread execution, and webpack-parallel-ugliffe -plugin can execute the development environment in parallel without meaningless operations

Many configurations do not need to be done in the development stage, we can distinguish between development and online two sets of configuration, so that when the need to go online can be fully compiled, such as code compression, directory content cleaning, file hash calculation, extraction of CSS files, etc

Babel-loader enables caching

When babel-loader is executed, it may generate some common files that are repeated during runtime, resulting in large and redundant code and slowing down compilation efficiency

You can add the cacheDirectory parameter or use the transform-Runtime plug-in

// webpack.config.js
use: [{
    loader: 'babel-loader',
    options: {
        cacheDirectory: true
    }]


// .bablerc
{
    "presets": [
        "env",
        "react"
    ],
    "plugins": ["transform-runtime"]
    
}
Copy the code

Use Happypack to speed up builds

Happypack uses multiple processes to package buildsCopy the code

Optimize the search path alias at build time

Using noParse

When webPack is packaged, sometimes we don’t need to resolve the load of modules (modules that are not dependent or modularized at all), so we can just add this parameter and skip the parsing

module:{
noParse: /node_modules\/(jquery.js)
}
Copy the code

Enable DllPlugin and DllReferencePlugin precompiled library files

This is one of the most complex and improved steps, and the principle is to package the third-party library files separately, so that subsequent compilations do not need to package the third-party library during compilation

Copy static resource files and introduce DllPlugin and DllReferencePlugin to build some third-party libraries ahead of time to optimize Webpack Apo.

In a production environment, the pre-built packages need to be synchronized to dist

Every time for commonChunkPlugin webpack packaging actually still need to deal with these third-party libraries, just after packaging, can separate the third-party libraries and our own code. DllPlugin, on the other hand, can completely separate third-party code, packaging only the project’s own code at a time. Create a new webpack.dll.config.js file under build/ and copy the code:

Const path = require("path") const webpack = require("webpack") module.exports = { ['vue/dist/vue.esm.js', 'axios', 'vue-router', 'vuex'] }, output: { path: path.join(__dirname, '.. Filename: '[name].dll. Js ', Library: '[name]_library'}, plugins: [ new webpack.DllPlugin({ path: path.join(__dirname, '.', '[name]-manifest.json'), name: '[name]_library', context: __dirname}), / / compression packaged files new webpack. Optimize the UglifyJsPlugin ({compress: {warnings: false}})]}Copy the code

In the build/webpack. Dev. Config. Js and build/webpack. Prod. Config. Add plugins js

	new webpack.DllReferencePlugin({
	      context: __dirname,
	      manifest: require('./vendor-manifest.json')
	}),
Copy the code

Introduce the precompiled libraries under index.html in the root directory

 	<script src="./static/js/vendor.dll.js"></script>
Copy the code

Add the DLL command under package.json/scripts

"dll": "webpack --config ./build/webpack.dll.config.js"
Copy the code

Run:

npm run dll
Copy the code

then

NPM run dev or NPM run buildCopy the code

Extracting common modules using the CommonsChunkplugin reduces file size and also helps file caching at the browser layer

NPM run DLL NPM run dev or NPM run buildCopy the code