Package optimization strategy

  • Webpackage 4.0 Packaging Optimization Strategy (I)
  • Webpackage 4.0 Packaging Optimization Strategy (II)
  • Webpackage 4.0 Packaging Optimization Strategy (iii)

Distinguish between development and production environments

Often we need to differentiate build environments when developing web pages

  • Development An environment that facilitates development and debugging during development
  • Production The runtime environment published to be used online

Use the NPM command

Environment variables are set using the cross-env module

Cross-env sets and uses environment variables across platforms without having to worry about setting or using environment variables correctly for the platform.

npm i cross-env -D
Copy the code

Usage

The NPM scripts:

{
    "scripts": {
        "build": "cross-env NODE_ENV=production webpack --mode production"."dev": "cross-env NODE_ENV=development webpack-dev-server --mode development",}}Copy the code

Run the NPM command to switch the environment

NPM run build // Production environment process.env.node_env ==='production'NPM run dev // Development environment process.env.node_env ==='development'
Copy the code

We can then use process.env.node_env in webpack.config.js to get the current environment identity

Distinguish environments in code

Defining environment Constants

Webpack4 used to define the NODE_ENV environment variable via DefinePlugin to determine what should be referenced in the library.

NODE_ENV is an environment variable exposed by Node.js to execute scripts. It is often used to determine the behavior of service tools, build scripts, and client libraries in development versus production environments.

Add the DefinePlugin plugin to webpack.config.js

const webpack = require('webpack');

plugins: [
    new webpack.DefinePlugn({
       'process.env': {
           'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
       }
    })
]
Copy the code

The corresponding logic is executed in main.js by judging the process.env.node_env constant

Mode Mode Configuration

– Added the mode configuration in Webpack4 to specify process.env.node_env in the browser environment. The default value is development, but cross-env is still required in the Node environment. Mode is a new parameter added to WebPack 4 and has two optional values: Production and development. Mode cannot be default. You can select either of the following:

Production mode:
  • 1. Many code optimizations are turned on by default in production (Minify, Splite, etc.)
  • 2. Enable gaze and validation during development and automatically add eval DevTool
  • 3. The production environment does not support watching, and the development environment optimizes the speed of repackaging
  • 4. The default opens the Scope hoisting and Tree – shaking (the original ModuleConcatenationPlugin)
  • 5. Set process.env.node_env to different environments automatically, so there is no need to DefinePlugin to do this
  • 6. If you set mode to None, all defaults are removed
  • 7. Webpack will be alerted if you don’t add this configuration, so add it anyway

Development mode:

  • 1. Optimized incremental build speed and development experience

  • 2. Process.env.node_env does not need to be defined. The default value is development

  • 3. Support comments and hints in development mode, and support Source maps under Eval

const NODE_ENV = process.env.NODE_ENV;
if (NODE_ENV === 'development'Console.log (console.log) {console.log(console.log)'development', NODE_ENV);
} else{// The production environment executes the following environment console.log('production', NODE_ENV);
}

Copy the code

DefinePlugn

DefinePlugin allows you to create a global constant that can be configured at compile time. This can be very useful when the development mode and the release mode are built to allow different behaviors.

Differentiating environments in webPack configuration

Add the WebPack configuration file in the project directory

  • Webpack.base.config.js holds the common configuration files for the webPack base
  • Webpack.dev.config.js saves the webPack development environment configuration file
  • Webpack.prod.config.js saves the webPack build environment configuration file
  • Webpack.config. js Webpack execution configuration file saves the configuration of the corresponding environment and the combined configuration of the webPack base configuration file

Basic configuration webpack.base.config.js

Webpack some loader configuration

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const HappyPack = require('happypack');
const os = require('os'); // const happyThreadPool = happypack.threadpool ({size: os.cpus().length}); // Specify the number of thread poolsfunction resolve(dir) {
    return path.join(__dirname, dir);
}

module.exports = {
    entry: {
        app: './src/main.js'
    },
    output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                // use: 'babel-loader? cacheDirectory'
                use: 'happypack/loader? id=babel'Exclude: /node_modules/, // Exclude: /node_modules/ include: path.resolve(__dirname,'src') // Specify the folder to load}], noParse:function(content) {// content The module path to parse from the entryreturn/no-parser/.test(content); / / returntrue}}, resolve: {modules: [//'src'),
            resolve('node_modules') // specify the node_modules location when you import third-party modules directly from this path],alias: {
            funs$: resolve('src/util/funs.js')
        },
        extensions: ['.js'.'.vue'}, plugins: [new webpack.defineplugin ({// define environment variables"process.env": JSON.stringify(process.env.NODE_ENV)
        }),
        new HappyPack({
            id: 'babel',
            loaders: ['babel-loader? cacheDirectory'],
            threadPool: happyThreadPool,
            verbose: true
        }),
        new HtmlWebpackPlugin({
            template: resolve('index.html'),
            title: 'hello webpack! '}})]Copy the code

Develop and configure webpack.dev.config.js

Development input/output and development debugging configuration such as devServer devTool configuration

const webpack = require('webpack');

module.exports = {
    plugins: [
       new webpack.DefinePlugin({
           'process.env': {
               'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
           }
       })
    ],
    devServer: {
        contentBase: resolve('dist'),
        compress: true,
        port: 9000
    }
};
Copy the code

Generate the environment webpack.prod.config.js

Generate environment for code separation and other code optimization on line configuration

const webpack = require('webpack');
const path = require('path');
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlIncludeAssetsPlugin = require('html-webpack-include-assets-plugin');

module.exports = {
    plugins: [
        new webpack.DllReferencePlugin({
            manifest: require(path.join(__dirname, 'dll'.'react.manifest.json'))}), new ParallelUglifyPlugin ({workerCount: 4, / / open a few child processes to the execution of concurrent compression, the default is the current computer CPU number minus 1 uglifyJS: {output: {beautify:false// No need to format comments:false// Keep comments}, compress: {warnings:false// Uglifyjs delete no warning when there is no code // drop_console:trueCollapse_vars: // Delete all console statements collapse_vars:true,
                    reduce_vars: true
                }
            }
        }),
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'index.html')
        }),
        new HtmlIncludeAssetsPlugin({
            assets: ['/dll/react.dll.js'],
            append: false}})];Copy the code

Webpack.config.js configuration merge

Merge base configuration and corresponding environment configuration into ‘webpack.config.js’ with webpack-merge

npm i webpack-merge -D
Copy the code

webpack.config.js

const base = require('./webpack.base.config');
const merge = require('webpack-merge');

let config;
if (process.env.NODE_ENV === 'production') {
    config = require('./webpack.prod.config');
} else {
    config = require('./webpack.dev.config');
}

module.exports = merge(base, config);
Copy the code

Run production configuration

npm run build
Copy the code

Run the development configuration

npm run dev
Copy the code

Live reloading and module hot replacement (HMR)

Webpack-dev-server gives you a simple Web server that can live reloading.

Let’s set the following:

    npm i webpack-dev-server -D
Copy the code

Configuration webpack. Dev. Config. Js

devServer: {
    contentBase: path.join(__dirname, 'dist'), // make the files in the dist directory as accessible files. compress:truePort: 9000, // Port number inline:true// Inject a websocket client into the packaged file}Copy the code

npm scripts

{
    "scripts": {
        "dev": "cross-env NODE_ENV=development webpack-dev-server --mode development"}}Copy the code

Start the server

npm run dev
Copy the code

Browser access localhost:9000 when changing the code CTRL + S will automatically refresh the browser

Enable the HMR

Hot Module Replacement (or HMR) is one of the most useful features webPack provides. It allows various modules to be updated at run time without a complete refresh.

Configuration webpack. Dev. Config. Js

devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000,
    inline: true,
    hot: true// enable HMR}Copy the code

Pay attention to In addition we also need to add NamedModulesPlugin and HotModuleReplacementPlugin plug-in

webpack.dev.config.js

{
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ]
}
Copy the code

Other code and frameworks turn on hot replacement

1.React Hot Loader

Install

npm install react-hot-loader
Copy the code

Getting started

Add react-hot-loader/ Babel to your.babelrc:

// .babelrc

{
    "plugins": ["react-hot-loader/babel"]}Copy the code

1.2 Mark your root component as hot-exported:

// App.js
import React from 'react'
import { hot } from 'react-hot-loader'const App = () => <div>Hello World! </div>export default hot(module)(App)
Copy the code

2.Vue loader

Vue-cli is already integrated with vue-CLI scaffolding development

  • react-hot-loader
  • vue-loader

HMR modifies the stylesheet

With the help of style-loader, module hot replacement of CSS is actually quite simple.

Install the following loader:

npm i style-loader css-loader -D
Copy the code

HMR Reference configuration

  • HMR reference