The learning notes according to the B site tutorial, the tutorial address: www.bilibili.com/video/BV1a4…

A list,

Dependent version:

"devDependencies": {
    "html-webpack-plugin": "^ 3.2.0"."webpack": "4.43.0"."webpack-cli": "3.3.12"."webpack-dev-server": "3.11.0"
}
Copy the code

1.1 the introduction

Webpack is a modern static module bundler. When WebPack works on an application, she recursively builds a Dependency graph of each module the application needs, which is then packaged into one or more bundles

1.2 Core Concepts

1.2.1 Entry

The starting point of the entry indicates which modules the WebPack application uses as a starting point for building its internal dependency diagram. Once inside the entry point, WebPack finds out which modules and libraries are (directly and indirectly) dependent on the entry point.

You can specify the starting point of an entry (or multiple entries) through the Entry property in the WebPack configuration. The default entry file is./ SRC

//webapck.config.js
module.exports = {
	entry:'./src/main.js'
}
Copy the code

1.2.2 Output

The Output attribute tells WebPack where to export the bunldes built and how to name them, with the default path being./dist. Basically the entire application structure is compiled into the output path folder.

let path = require('path');
module.exports = {
    mode: "development".// Mode defaults to two production development types
    entry: './src/index.js'./ / the entry
    output: {
        filename: "bundle.js".// The packaged name
        path: path.resolve(__dirname,'dist') // The packaged path must be an absolute path}}Copy the code

1.2.3 Loader

Loader allows Webpack to process files that are not JavaScript (Webpack itself can only process JavaScript). Loader can convert all types of file processing into valid modules that WebPack can handle. They can then be processed using the packaging capabilities of WebPack.

Essentially, WebPack Loader converts all types of files into modules that the application’s dependency graph can reference directly.

Note: Loader can import any type of module (such as CSS files), which is unique to WebPack and may not be supported by other packers or task executors.

1.2.4 Plugin

Two, installation environment

yarn add webpack webpack-cli -D

or

npm install webpack webpack-cli –save-dev

Three, environment configuration

3.1 Basic Environment Configuration

Webpack itself can package JS files, here the basic configuration package JS, and output

let path = require('path');
module.exports = {
    mode: "development".// Mode defaults to two production development types
    entry: './src/index.js'./ / the entry
    output: {
        filename: "bundle.js".// The packaged name
        path: path.resolve(__dirname,'dist') // The packaged path must be an absolute path}}Copy the code

Results:

3.2 Configuring development Services

In the development environment, pages need to be accessed in a browser. Webpack provides the WebPack-dev-server development library (with the Express service built in), which generates a package file in memory when the service starts.

1. Install library files

Yarn add [email protected] - DCopy the code

2. Add the configuration

// webpack.config.js
module.exports = {
    devServer: {port: 3000.progress: true.contentBase: './dist'.compress: true}}Copy the code

3, run,

// Configure it in package.json"dev": "webpack-dev-server"
 ----------------------------------
 npm run dev
Copy the code

4, test,

3.3 packaging HTML

1. Install library files

yarn add html-webpack-plugin@3.2.0 -D
Copy the code

2. Add the configuration

let HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
     plugins: [ // Array to store all webPack plugins
        new HtmlWebpackPlugin({
            template: "./src/index.html".filename: "index.html"}})]Copy the code

3, run,

npm run dev
Copy the code

4, test,

3.4 Style Processing (Style)

1, the introduction

By default, webpack can only parse JS files. CSS files cannot be parsed. CSS files need to be parsed by CSS-loader, and the style-loader is used to insert the CSS file contents into the head tag of index. HTML

2. Install the Loader

npm install css-loader style-loader --save-dev
# or
yarn add css-loader style-loader -D
Copy the code

3. Add CSS files and references

/* src/base.css */
body{
    color: yellow; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --/* src/index.css */

@import './base.css';
body{
    background: red;
}

Copy the code
// index.js
require("./index.css")
Copy the code

4. Write the configuration

  1. Css-loader parses the @import syntax
  2. The style-loader function inserts CSS into the head tag of index. HTML
  3. Loader usage: Only one loader is used to configure strings in use
  4. Multiple Loaders require arrays[]
  5. The parse sequence of the loader is from top to bottom
  6. Loaders can also be written as objects
// webpack.config.js
module.exports = {
    module: {
        rules: [
            { 
                test: /\.css$/,
                use: [
                    {
                        loader: 'style-loader',
                        options: {
                            // Set the position where the style is insertedinsert: function(element){ var parent = document.querySelector('head'); var lastInsertedElement = window._lastElementInsertedByStyleLoader; if (! lastInsertedElement) { parent.insertBefore(element, parent.firstChild); } else if (lastInsertedElement.nextSibling) { parent.insertBefore(element, lastInsertedElement.nextSibling) } else { parent.appendChild(element) } } } },"css-loader"}]}}Copy the code

5, test,

6. Add less parsing

  1. NPM install less less-loader –save-dev
  1. Write less files and references
// index.less
body{
    div{
        border: 1px solid #dadada; }}Copy the code
  1. Write the configuration
// webpack.config.js
module.exports = {
    module: {
        rules: [
           
            { 
                test: /\.less$/,
                use: [
                    {
                        loader: 'style-loader',
                       
                    },
                    "css-loader"./ / parsing @ import
                    "less-loader" // Convert less to CSS}]}}Copy the code
  1. test

3.5 Style Processing (link)

Problem: Before using CSS-loader and style-loader to process CSS files, the CSS content is inserted into the HEAD tag of the HTML file. What if you want to use the tag to import into HTML?

Answer: Use mini-CSs-extract-plugin to extract CSS plugins

1. Install the plug-in

npm install mini-css-extract-plugin --save-dev
Copy the code

2. Write the configuration

/ / introduction
let MiniCssExtractPlugin = require("mini-css-extract-plugin")

plugins: [ 
    new MiniCssExtractPlugin({// Configure the plug-in
        filename: "main.css",
    })
],

module: {
    rules: [
        { 
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,// Replace the style-loader with the loader that removes the plug-in
                "css-loader"
            ]
        },
        { 
            test: /\.less$/,
            use: [
                MiniCssExtractPlugin.loader,// Replace the style-loader with the loader that removes the plug-in
                "css-loader"./ / parsing @ import
                "less-loader" // Convert less to CSS]]}}Copy the code

3, test,

3.6 Style Processing (Adding Prefixes)

1. Install the plug-in

npm install postcss-loader autoprefixer --save-dev
Copy the code

2. Add styles

/* index.css */
body{
    transform: rotate(45deg);
}
Copy the code

3. Write the configuration

// Add postcss-loader to webpack.config.js
module: {
    rules: [{test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader"."postcss-loader"] {},test: /\.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader"./ / parsing @ import
                "postcss-loader"."less-loader"]]}}Copy the code
// Add browser support to package.json, otherwise the styles in the packaged CSS will not be prefixed
"browserslist": [
    "defaults"."not ie <= 8"."last 2 versions"."1%" >."iOS >= 7"."Android > = 4.0"
]

Copy the code

4, test,

npm run build
Copy the code
/* The result of the package in main.css */
body{
    color: yellow;
}
body{
    background: red;
    -webkit-transform: rotate(45deg);
            transform: rotate(45deg);
}
body div {
  border: 1px solid #dadada;
}


Copy the code

3.7 Style Processing (Compression)

1. Install the plug-in

npm install css-minimizer-webpack-plugin --save-dev
Copy the code

2. Write the configuration

// webpack.config.js
mode: "production"// Change to production mode

// Set optimization items
let CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
optimization: { / / optimization
    minimizer: [new CssMinimizerPlugin()
    ]
}

Copy the code

3, test,

3.8 Converting ES6 syntax

3.8.1 Arrow function

1. Install dependencies

npm install babel-loader @babel/core @babel/preset-env --save-dev
Copy the code

2. Write functions

let fn = () = > {
    console.log("fn....")
}
fn();
Copy the code

3. Write a configuration file

module: {
        rules: [{test: /\.js$/,
                use: {
                    loader:"babel-loader".options: {presets: ['@babel/preset-env'].plugins:[
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ["@babel/plugin-proposal-class-properties", { "loose" : true}]}}}]}Copy the code

4, test,

3.8.2 class conversion

1. Install dependencies

npm install @babel/plugin-proposal-class-properties --save-dev
Copy the code

2. Write class files

class Person{
    name = "John"
}
let p = new Person()
console.log(p.name)
Copy the code

3. Write a configuration file

module: {
        rules: [{test: /\.js$/,
                use: {
                    loader:"babel-loader".options: {presets: ['@babel/preset-env'].plugins: ["@babel/plugin-proposal-class-properties"}}}]}Copy the code

4, test,

3.8.3 Decoration Class Conversion

1. Install dependencies

npm install @babel/plugin-proposal-decorators --save-dev
Copy the code

2. Write decorator class files

@log
class Person{
    name = "John"
}
let p = new Person()
console.log(p.name)
function log(target){
    console.log(target)
}

Copy the code

3. Write a configuration file

module: {
        rules: [{test: /\.js$/,
                use: {
                    loader:"babel-loader".options: {presets: ['@babel/preset-env'].plugins:[
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ["@babel/plugin-proposal-class-properties", { "loose" : true}]}}}]}Copy the code

4, test,

3.9 Processing JS syntax and verification

3.9.1 Handling ES6 Syntax

1. Install dependencies

npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
Copy the code

2. Write test files

// require("./a.js")
module.exports = Beans

class Beans{}function * gen(params){
    yield 1;
}

console.log(gen().next())
Copy the code

3. Write a configuration file

module: {
    rules: [{test: /\.js$/,
            use: {
                loader:"babel-loader".options: {presets: ['@babel/preset-env'].plugins: ["@babel/plugin-transform-runtime"]}},include:path.join(__dirname,'src'),
            exclude:/node_modules/]}},Copy the code

4, test: NPX webpack

3.9.2 Processing includes Syntax

1. Install dependencies

npm install @babel/polyfill  --save
Copy the code

2. Write test files

// Add an includes test statement to a.js
"aaa".includes('a')
Copy the code

3. Write a configuration file

// reference in a.js
require('@babel/polyfill')
Copy the code

4. Test: execute NPM webpack

3.9.3 JS syntax verification

1. Install dependencies

npm install eslint eslint-loader --save-dev
Copy the code

2. Download the esLint configuration file and place it in the root directory of your project (eslint.org/demo). ., final name.eslintrc.json. You can also configure the.eslintrc.js file in the project root directory yourself

// .eslintrc.js
// http://eslint.org/docs/user-guide/configuring

module.exports = {
  // This is used to tell ESLint that the current configuration file cannot be looked up by its parent
  root: true.// This is used to specify esLint parsers. Parsers must conform to the rules. The babel-esLint parser is a wrapper around the Babel parser that parses with ESLint
  parser: 'babel-eslint'.// This item is used to specify javaScript language type and style, sourceType is used to specify the js import method, the default is script, set to module, refers to a block import method
  parserOptions: {
      sourceType: 'module'
  },
  // This specifies the global variable of the environment. The following configuration specifies the browser environment
  env: {
      browser: true,},// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
  // This item is used to configure the standard JS style, that is to say, when writing code should be written properly, if you use VS-code I think it should avoid errors
  extends: 'standard'.// required to lint *.vue files
  // This item is used to provide the plugin, the plugin name omits eslint-plugin-, and the following configuration is used to standardize HTML
  plugins: [
      'html'].// add your custom rules here
  // The following rules are used to set rules for normative code from plugins, using the prefix eslint-plugin- that must be removed
  // There are mainly the following setting rules, can be set to string or number, both effect is the same
  // "off" -> 0 turns off the rule
  // "warn" -> 1 Enables the warning rule
  //"error" -> 2 Enables the error rule
  // The following code can be read as well
  'rules': {
      // allow paren-less arrow functions
      'arrow-parens': 0.// allow async-await
      'generator-star-spacing': 0.// allow debugger during development
      'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0}}Copy the code

3. Write a configuration file

module: {
    rules: [{test: /\.js$/,
            use: {
                loader: "eslint-loader".options: {
                    enforce: "pre" // Pre is executed before post, and post is executed after post}},exclude:/node_modules/]}},Copy the code

4, test: NPX webpack, after running if the prompt which dependency is not installed, install which dependency

3.10 Introduction of global variables

Using jQuery as an example, you can use it in the following ways:

npm install jquery --save-dev
Copy the code
// Reference this in the js module
import $ from 'jquery'
Copy the code

3.10.1 Exposure to global Windows

1. Install dependencies

npm install expose-loader --save-dev
Copy the code

2. Configuration files

// Global exposure
//import $ from "expose-loader? exposes[]=$&exposes[]=jQuery! jquery";

// webpack.config.js
rules: [{test: require.resolve("jquery"),
        loader: "expose-loader".options: {
            exposes: ["$"."jQuery"],}},]Copy the code

3, test,

console.log(window.$)
Copy the code

3.10.2 ProvidePlugin

$is introduced in each module

1. Write a configuration file

// webpack.config.js
plugins: [    
    new webpack.ProvidePlugin({ // in each module
        $: "jquery"})].Copy the code

2, test,

console.log($)
Copy the code

3.10.3 Introducing Packaging

1. Add jQuery CDN path to index. HTML

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Copy the code

2. Write a configuration file

// webpack.config.js
externals: {
    jquery: "jQuery"
},
Copy the code

3, test,

  • In no configurationexternals

  • Configure theexternals

3.11 Image processing

3.11.1 Create images in JS to introduce

1. Install dependencies

cnpm install file-loader --save-dev 
Copy the code

2. Add the configuration

module: {
	rules: [{test: /\.(png|jpg|gif)$/,
            use: "file-loader"  // It is customary to use url-loader to process images}}]Copy the code

3. Create an image in JS

import logo from './logo.png'
let image = new Image();
image.src = logo;
document.body.appendChild(image);
Copy the code

4, test,

3.11.2 Introducing images in the CSS

1. Install dependencies

cnpm install css-loader --save-dev
Copy the code

Note: CSS-loader will change the URL (“./logo.png”) in the CSS file to the URL (require(“./logo.png”)).

2. Add the configuration

module: {
	rules: [{test: /\.css$/,
            use: "css-loader"}}]Copy the code

3. Write CSS code

body{
    background: url("./logo.png")}Copy the code

4, test,

3.11.3 Introducing images in HTML

1. Install dependencies

cnpm install html-withimg-loader --save-dev
Copy the code

2. Add the configuration

module: {
	rules: [{test: /\.html$/,
            use: "html-withimg-loader"
        },
        {
            test: /\.(png|jpg|gif)$/,
            use:[{
                loader:'file-loader'.options: {esModule:false // Resolve an htML-webpack-plugin conflict}}]}Copy the code

Note: the html-withimg-loader and file-loader versions are incompatible with the 5.* version and cannot be packaged. EsModule :false

3. Write code

<! Add code to index.html -->
<img src="./logo.png" />
Copy the code

4, test,

3.11.4 Package images as Base64

1. Install dependencies

cnpm install url-loader -save-dev 
Copy the code

2. Add the configuration

module: {
	rules: [{test: /\.html$/,
            use: "html-withimg-loader"
        },
        {
            test: /\.(png|jpg|gif)$/,
            use:[{
                loader:'url-loader'.// file-loader is integrated with url-loader
                options: {limit: 10 * 1024.// Set the threshold under which the image is converted to base64, otherwise use file-loader
                	esModule:false // Resolve an htML-webpack-plugin conflict}}]}Copy the code

3. Write code

 <img src="./logo.png">
Copy the code

4, test,

3.12 Classification of Packaged Files

1, picture packaging specified path

module: {
	rules: [{test: /\.html$/,
            use: "html-withimg-loader"
        },
        {
            test: /\.(png|jpg|gif)$/,
            use:[{
                loader:'url-loader'.// file-loader is integrated with url-loader
                options: {limit: 10 * 1024.// Set the threshold under which the image is converted to base64, otherwise use file-loader
                	esModule:false.// Resolve an htML-webpack-plugin conflict
                	outputPath: "/img/" // Package the image into this path}}]}Copy the code

2. Package CSS styles to the specified path

new MiniCssExtractPlugin({
	filename: "css/main.css",})Copy the code

3. Add the access domain name before the global CSS and image path

output: {
    publicPath: 'http://www.chtgeo.com' // Global public path
},
Copy the code

4. Add a separate path to CSS or image files

{
    test: /\.(png|jpg|gif)$/,
    use:[{
        loader:'url-loader'.options: {limit: 1.esModule:false.outputPath: "/img/".publicPath: 'http://www.chtgeo.com' // Add the public domain path to the image type}}}]Copy the code

3.13 Packaging Multi-Page Applications

1. Create a new project. Create 2 JS files and 1 index. HTML template file

//1. Create the webpack-dev folder

/ / SRC/new index. Js
console.log("this is index")
/ / SRC/new other. Js
console.log("this is other")

Copy the code

2. Initialize the project and add the WebPack environment

#Initialization engineering
npm init -y

#Install webPack dependencies
cnpm install webpack webpack-cli --save-dev

#HTML - webpack - the plugin installation
cnpm install html-webpack-plugin --save-dev
Copy the code

3. Write a configuration file

// webpack.config.js
let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports={
    mode:"development".entry: {home: "./src/index.js".other:"./src/other.js"
    },

    output: {
        filename: "[name].js".path: path.resolve(__dirname,"dist")},plugins: [new HtmlWebpackPlugin({
            template: "./index.html".filename: "home.html".chunks: ["home"]}),new HtmlWebpackPlugin({
            template: "./index.html".filename: "other.html".chunks: ["other"]]}})Copy the code

4, test,

npx webpack
Copy the code

3.14 configure the source – the map

1. Source code mapping, which generates a separate sourceMap file with columns and rows that identify the current error. (Large and complete)

devtool:'source-map'
Copy the code

2. No separate files are generated, but rows and columns can be displayed

devtool:'eval-source-map'
Copy the code

3. No columns will be generated, but separate mapping files will be generated, and the generated files can be retained

devtool:'cheap-module-source-map'
Copy the code

4, will not generate files, integrated in the packaged file, will not generate columns

devtool:"cheap-module-eval-source-map"
Copy the code

3.15 Usage of Watch

Webpack can listen for file changes and recompile when they are modified.

1. Enable listening

watch:true // The default is false
Copy the code

2. Configure the watchOptions option

watchOptions:{
    poll: 1000.// Specify milliseconds for polling
    aggregateTimeout:500.// Stabilization, when the first file changes, adds delay before rebuilding
    ignored:/node_modules/
}
Copy the code

3.16 Application of webpack plug-in

3.16.1 cleanWebpackPlugin Cleans and deletes plug-ins

1. Install dependencies

cnpm install clean-webpack-plugin --save-dev
Copy the code

2. Add the configuration

const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [ // Array to store all webPack plugins
	new CleanWebpackPlugin()
],
Copy the code

3, test: clear the files in the dist folder

3.16.2 copyWebpackPlugin Copies static files

1. Install dependencies: Note: The installed version is 4.4.3, and the configuration has changed in the latest version

CNPM install [email protected] - save - devCopy the code

2. Add the configuration

const CopyWebpackPlugin = require('copy-webpack-plugin')
plugins: [ // Array to store all webPack plugins
    new CopyWebpackPlugin([
        { from: path.resolve(__dirname, "doc"),to: "./doc"}]]Copy the code

3, test,

3.16.3 bannerPlugin Copyright plug-in

1. Installation dependency: The modified plug-in is webpack’s own plug-in and does not need to be installed separately

2. Add the configuration

let webpack = require('webpack')
plugins: [ // Array to store all webPack plugins
    new webpack.BannerPlugin("make 2021 by jinshw")]Copy the code

3, test,

3.17 Webpack cross domain issues

3.17.1 The first type: agency

In the first case, the server is not developed by itself, the front end needs to request the server interface data, and the front end needs the proxy itself

1, write a server test program

// server.js 
let express = require('express')

let app = express()


app.get("/user".(req,res) = > {
    res.json({name:"Test"})
})

app.listen(3000)

Copy the code

2. Write front-end request interface program

// Front-end request
let xhr = new XMLHttpRequest();
xhr.open('GET'."/api/user".true)

xhr.onload =function(){
    console.log(xhr.response)
}

xhr.send();
Copy the code

3. Add a proxy to the front end

// webpack.config.js
devServer: {proxy: {// Proxies requests to the server in the form of overrides
        "/api": {target: "http://localhost:3000".pathRewrite: { "/api":""}}}}Copy the code

4, test,

3.17.2 The second type: the front end needs analog data

Second: the front end just wants to simulate the data separately

1. Write front-end request interface program

// Front-end request
let xhr = new XMLHttpRequest();
xhr.open('GET'."/user".true)

xhr.onload =function(){
    console.log(xhr.response)
}

xhr.send();
Copy the code

2. Add the configuration

// webpack.config.js
devServer: {before(app){
        app.get("/user".(req,res) = > {
            res.json({name:"Test - before"}}})})Copy the code

3, test,

3.17.3 The third type: with a server, no proxy is required

In the third case, there is a server, the front-end and the server are self-implemented, and you want to start the WebPack configuration in the server

1. Installation dependency: Pay attention to the version. The latest version 4.x.x is not compatible with the following configuration

CNPM install [email protected] - save - devCopy the code

2. Write server-side code and add webPack configuration

// server.js
let express = require('express')
let app = express()
let webpack = require('webpack')

/ / middleware
let middleware = require('webpack-dev-middleware')

let config = require('./webpack.config.js')

let compiler = webpack(config);

app.use(middleware(compiler))


app.get("/user".(req,res) = > {
    res.json({name:"Test - 3333"})
})

app.listen(3000)
Copy the code

3, test,

// Start the service
node ./server.js
Copy the code

Visit the front-end page: http://localhost:3000

Direct access to the interface on the browser address: http://localhost:3000/user

3.18 Configuring the Resolve attribute

3.18.1 Setting An Alias

Requirements: Sometimes it is necessary to import other third-party library files, such as bootstrap library files

1. Install dependencies

CNPM install bootstrap --save CNPM install popper.js -d # bootstrap 4.x.xCopy the code

2. Write test code

// Reference it in index.js
/ / without using an alias is, it can be reference import "bootstrap/dist/CSS/bootstrap CSS"
import "bootstrap" // Direct reference
Copy the code
<! --index.html-->
<div class="btn btn-danger">bootstrap-test</div>
Copy the code

3. Add the configuration

resolve:{// Parse the third-party package common
    modules: [path.resolve('node_modules')].alias: {
        bootstrap: "bootstrap/dist/css/bootstrap.css",}},Copy the code

4, test,

3.18.2 Main entry fields and files

Requirement: the previous step alias introduction is very long, so it is not very convenient, want to directly find the corresponding CSS file

1. Add the configuration

resolve:{// Parse the third-party package common
    modules: [path.resolve('node_modules')].mainFields: ['style'.'main'] // Find the entry field
    // alias: {// alias
    // bootstrap: "bootstrap/dist/css/bootstrap.css",
    // }

},
Copy the code

Note: the mainFields field is a field found in package.json in the library file under node_modules, as shown below, in bootstrap.

If you want to set the name of the entry file, you can

mainFiles:[]

2, test,

3.18.3 Setting the Extension Name

Requirement: Do not want to include suffix names when importing third-party files. For example, there is a style. CSS file that is introduced in index.js,

// Normal import mode
import './style.css' 

// Now I want to write
import './stype'
Copy the code

1. Write code

body {
    background-color: coral! important;
}
Copy the code
// index.js
import './style'
Copy the code

2. Add the configuration

resolve:{// Parse the third-party package common
    modules: [path.resolve('node_modules')].extensions: ['.js'.'.css'.'.vue'] // File name extension
    // mainFields: ['style','main'
    // alias: {// alias
    // bootstrap: "bootstrap/dist/css/bootstrap.css",
    // }
},
Copy the code

3, test,

3.19 Defining Environment Variables

Requirements: Use different urls for different environments (development, production)

1. Write code

let url= ""
if(DEV === 'dev'){
    url = "http://localhost:3000"
}else{
    url = "http://www.chtgeo.com"
}
console.log(url,", -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --")
console.log(FLAG,typeof FLAG)
console.log("EXPRESSION==",EXPRESSION)
Copy the code

2. Add the configuration

Note: WebPack comes with a custom plug-in that allows you to customize variables; The plugin converts the value of a custom variable directly to a variable instead of a string. If you want to define strings, json.stringify (“dev”) is recommended.

plugins:[
    new webpack.DefinePlugin({
        DEV: JSON.stringify('dev'), // console.log('dev')
        FLAG: 'true'.// console.log(true)
        EXPRESSION: '1 + 1' // console.log(1+1)}),]Copy the code

3, test,

3.20 Distinguish between different environments

1. Install dependencies

cnpm install webpack-merge --save-dev
Copy the code

2. Write a configuration file

// webpack.base.js common configuration
let path = require('path');
let HtmlWebpackPlugin = require("html-webpack-plugin")
let MiniCssExtractPlugin = require("mini-css-extract-plugin")
let CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { loader } = require('mini-css-extract-plugin');
let webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')


module.exports = {
    optimization: {
        minimizer: [new CssMinimizerPlugin()
        ]
    },
    resolve: {// Parse the third-party package common
        modules: [path.resolve('node_modules')].extensions: ['.js'.'.css'.'.vue'] // File name extension
    },
    devServer: {port: 8080.progress: true.contentBase: './dist'.compress: true.open: true,},// mode: "development", // Mode defaults to two types of production development
    entry: './src/index.js'./ / the entry
    
    watch:true.watchOptions: {poll: 1000.// Specify milliseconds for polling
        aggregateTimeout:500.// Stabilization, when the first file changes, adds delay before rebuilding
        ignored:/node_modules/
    },
    output: {
        filename: "bundle.js".// The packaged name
        path: path.resolve(__dirname,'dist'), // The packaged path must be an absolute path
        // publicPath: 'http://www.chtgeo.com'
    },

    plugins: [ // Array to store all webPack plugins. ] .module: {... }}Copy the code
// webpack.prod.js is configured for the production environment
let { merge } = require('webpack-merge')
let base = require('./webpack.base.js')

module.exports = merge(base,{
    mode:'production',})Copy the code
// webpack.dev.js test environment configuration
let { merge } = require('webpack-merge')
let base = require('./webpack.base.js')

module.exports = merge(base,{
    mode: "development",})Copy the code

3. Add a run command

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

4. Run tests

npm run build:dev
#Result uncompressed
Copy the code

npm run build:prod
#The result is already compressed
Copy the code

3.21 webpack optimization

3.21.1 noParse

Requirements: Sometimes, when using third-party packages, it is clear that there are no dependencies in the third package and there is no need to parse third-party packages; NoParse is not parsed. We use the jquery library to test it

1. Install dependencies

cnpm install jquery --save
Copy the code

2. Write code

// index.js
import $ from 'jquery'
Copy the code

3. Add the configuration

// webpack.config.js
module: {
	noParse: /jquery/,}Copy the code

4, test,

Not configured noParse

Set the noParse

3.21.2 IgnorePlugin

Requirement: When importing third-party packages, you want to ignore some references in third-party packages, such as reference to the moment library, and do not want to package the language packages in this library

1. Install dependencies

cnpm install moment --save
Copy the code

2. Write programs

// index.js
import moment from 'moment'
moment.locale('zh-cn')
let r = moment().endOf('day').fromNow()
console.log(r)
Copy the code

3. Add the configuration

// webpack.config.js
plugins: [ 
	new webpack.IgnorePlugin(/\.\/locale/./moment/),]Copy the code

4, test,

Configure the IgnorePlugin

IgnorePlugin is not configured and can be introduced in JS

// Set the language
// moment.locale('zh-cn')
// Manually import the required language
import 'moment/locale/zh-cn'
Copy the code

5. Exclude and include as follows:

{
    test: /\.js$/,
    use: {
        loader:"babel-loader".options: {presets: ['@babel/preset-env'].plugins:[
                ["@babel/plugin-proposal-decorators", { "legacy": true }],
                ["@babel/plugin-proposal-class-properties", { "loose" : true}]."@babel/plugin-transform-runtime"]}},include:path.join(__dirname,'src'),
    exclude:/node_modules/
},
Copy the code

3.21.3 dllPlugin

Requirements: Package third-party library files into dynamic libraries, such as React

1. Install dependencies

cnpm install @babel/preset-react --save-dev
cnpm install react react-dom --save-dev
Copy the code

2. Write code

<! --index.html-->
<div id="root"></div>
Copy the code
// index.js
import React from 'react';
import { render } from 'react-dom';
render(<h1>jsx</h1>.window.root)
Copy the code

3. Add the configuration

A. Add the React dependency configuration

// webpack.config.js
{
    test: /\.js$/,
    use: {
        loader:"babel-loader".options: {presets: ['@babel/preset-env'.'@babel/preset-react']}}},Copy the code

B. Compile the webpack.react.js file

// webpack.react.js
let path = require('path')
let webpack = require('webpack')

module.exports = {
    mode: 'development'.entry: {react: ['react'.'react-dom']},output: {filename:'_dll_[name].js'.path:path.join(__dirname,'dist'),
        library:'_dll_[name]'.// libraryTarget:'var' // commonjs var this ...
    },
    plugins: [new webpack.DllPlugin({
            name:"_dll_[name]".path:path.join(__dirname,'dist'.'manifest.json'),}})]Copy the code

C. Run to generate the dynamic library file

npx webpack --config webpack.react.js
Copy the code

D. Add the configuration to the main configuration file webpack.config.js

plugins: [
    new webpack.DllReferencePlugin({
        manifest:path.join(__dirname, 'dist'.'manifest.json'),})]Copy the code

E. Introduce dynamic library JS files in index. HTML

<script src="/_dll_react.js"></script>
Copy the code

4, test,

#Make sure you have executed NPX webpack --config webpack.react.js to generate the dynamic library file
npm run dev
Copy the code

3.21.4 happypack

Requirements: When the project is very large and packaging is very slow, consider multi-threaded packaging, using the Happypack plugin

1. Install dependencies

cnpm install happypack --save-dev
Copy the code

2. Add the configuration

const Happypack = require('happypack')
module: {
    rules: [{test: /\.js$/,
            use: 'Happypack/loader? id=js'.include:path.join(__dirname,'src'),
            exclude:/node_modules/]}},// Happypack-- the id must be the same as the id specified in rules (use: 'Happypack/loader? Id = js')
plugins: [
    new Happypack({
        id:"js".use: [{loader:"babel-loader".options: {presets: ['@babel/preset-env'.'@babel/preset-react'].plugins:[
                        ["@babel/plugin-proposal-decorators", { "legacy": true }],
                        ["@babel/plugin-proposal-class-properties", { "loose" : true}]."@babel/plugin-transform-runtime"]}}]}),]Copy the code

3. Test: 3 threads are enabled by default

3.21.5 WebPack comes with optimizations

Treeshaking automatically removes code that is not used. Note that it works only if the production environment uses import XXX from ‘XXX’. Let XXX require(‘ XXX ‘

// test.js
let sum = (a,b) = > {
    return a + b + "sum";
}

let minus = (a,b) = > {
    return a - b + "minus";
}

export default {sum,minus}
Copy the code
// index.js
import {sum,minus} from './test.js';
console.log(calc.sum(1.2))
Copy the code
// If minimizer is configured in webpack.config.js, use the terser-webpack-plugin, otherwise tree-shaking does not work
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
    optimization: {
        minimizer: [new CssMinimizerPlugin(),
            new TerserPlugin()
        ]
    },
}
Copy the code

Note: when installing the terser-webpack-plugin library, note that the version of the terser-webpack-plugin library should be the same as the larger version of Webpack. In this case, the larger version of Webpack is 4, so the terser-webpack-plugin should also be 4.x.x

CNPM install [email protected] - save - devCopy the code

The scope hosting scope must be in production.

// test.js
let a = 1;
let b = 2;
let c = 3;
console.log(a+b+c,"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --")
Copy the code

3.22 Webpack removes common code from multiple pages

Requirement: In multi-page applications, multiple pages may reference common code, or a common third-party library file, so that the common code or third-party library file can be separated from a common file, and other pages reference the common page.

3.22.1 Extract common code

1. Write code

//aa.js
console.log("aa......")
Copy the code
//bb.js
console.log("bb......")
Copy the code
// index.js
import './aa'
import './bb'
console.log("other......")
Copy the code

2. Add the configuration

// webpack.config.js multi-page configuration modification
entry: {/ / the entry
    index:'./src/index.js'.other:'./src/other.js'
}, 
output: {/ / export
    filename: "[name].js".// The packaged name
    path: path.resolve(__dirname,'dist'), // The packaged path must be an absolute path
},
Copy the code
// webpack.config.js adds the extraction of common code configuration
optimization: {
    splitChunks: {// Split code blocks
        cacheGroups: {/ / cache group
            common: {// Public module
                chunks:'initial'.minSize:0.// If the public code is greater than or equal to minSize bytes, extract the public code
                minChunks:2 // Public code that is referred to more than or equal to minChunks will be removed}}}}Copy the code

3, test,

npm run build
Copy the code

3.22.2 Remove third-party code

1. Write code

/ / index. Js added
import $ from 'jquery'
console.log($)
Copy the code
/ / other. Js added
import $ from 'jquery'
console.log($)
Copy the code

2. Add the configuration

// Add vendor configuration in webpack.config.js
optimization: {
    splitChunks: {// Split code blocks
        cacheGroups: {/ / cache group
            common: {// Public module
                chunks:'initial'.minSize:0.// If the public code is greater than or equal to minSize bytes, extract the public code
                minChunks:2 // Public code that is referred to more than or equal to minChunks will be removed
            },
            vendor: {priority:1.// Weights must be configured; otherwise, common is removed first, and vendor cannot be removed
                test:/node_modules/.// Pull it out
                chunks:'initial'.minSize:0.// If the public code is greater than or equal to minSize bytes, extract the public code
                minChunks:2 // Public code that is referred to more than or equal to minChunks will be removed}}}}Copy the code

3, test,

npm run build
Copy the code

3.23 a lazy loading

Requirement: While the code is running, click the button to load the JS program. For example: click a button before loading the source.js file

1. Write code

// index.js
/ / lazy loading
let button = document.createElement('button');
button.innerHTML = "Lazy loading"
button.addEventListener('click'.function(){
    // Es6 draft syntax, jSONP implements dynamic file loading
    import('./source.js').then(data= > {
        console.log(data.default); })})document.body.appendChild(button);
Copy the code
// source.js
export default "chtgeo1"
Copy the code

2, test,

3.24 hot update

Requirement: after modifying the code at this stage, the page will be refreshed completely; Now you need a local update. After you change the code, don’t refresh the page, just a local update.

1. Write code

// source.js
export default "chtgeo1"
Copy the code

2. Add the configuration

// webpack.config.js
devServer: {hot:true,},plugins: [ 
    new webpack.NamedModulesPlugin(), // Prints the updated module path
    new webpack.HotModuleReplacementPlugin(), // Hot update plugin
]
Copy the code

3, test,