Webpack is the core, webpack-CLI is to provide us with the relevant commands, can be compiled and packaged based on webpack related commands.

Webpack Webpack-CLI is used to compile and package code during development. The packaged code is deployed on the server and distributed in production environment. So there is no need to compile and package in production environment, so install in development environment.

A, install,

NPM init -y NPM I webpack webpack-cli --save-devCopy the code

Two, zero configuration use

By default, Webpack will package and compile the files in the current project SRC directory (zero configuration entry default is index.js) into the dist file directory (WebPack supports Commonjs and ES6Module specifications in the process of compiling the code) and deploy them to the server in the future.

Run webpack

Method 1:

npx webpack
Copy the code

Method 2:

Configure executable commands in package.json

{
  "scripts": {
    "serve":"webpack"
  },
}

==>  npm run serve
Copy the code

Customize webPack configuration items

You can create two JS files: webpack.config.js/webpackfile.js the file name must not change

  • Write custom Webpack configuration items, later webpack compilation is packaged according to their own configuration of the content of the compilation process
  • This file is in the root directory
  • File name: webpack.config.js or webpackfile.js
  • Webpack itself is developed based on Node, so the module handling rules for configuration items refer to the CommonJs specification
Const path = require('path') module.exports = {// set compilation mode, development(only)/production(only) Default) mode:'production', // set the compiled entry file entry:'./ SRC /main.js', // set the compiled exit file output:{// Compiled file name [hash] The compiled file will randomly generate unique hash values in the name, Filename :'bundle.[hash].min.js', // filename:'bundle.min.js', // filename:'bundle.min.js', // Output directory (absolute path) path:path.resolve(__dirname,'build')}}Copy the code

4. Plugin

1. Install common plug-ins

Three common plug-ins are installed here

npm i html-webpack-plugin clean-webpack-plugin webpack-dev-server --save-dev
Copy the code

2. Common plug-ins

1) HTML – webpack – the plugin

Fix: Every time you change the code, you need to manually change the JS information imported into the specified HTML page after recompiling. This plug-in handles HTML compilation and import files automatically.

Note:

A) The entry HTML page (index.html) can be placed in the public directory

B) the index. HTML page is no longer written to introduce JS code

New HtmlWebpackPlugin({// template path) {// Use plugins in webpack :[// Configure the specified HTML page template (later compilation will automatically import compiled resource files into our page template) Template :'./public/index.html', // The compiled file filename:'index.html', // Whether to import the compiled resource file into the page, set the hash value (clear strong cache, same as the hash value in output), Minify :{// Delete the Spaces between tags collapseWhitespace:true, collapseWhitespace / / remove annotation removeComments: true, / / remove the div attribute double quotation marks, div = "XXX" removeAttributeQuotes: true, / / remove empty attribute < div class = "aa" id = "" > < / div > id as a whole will be deleted removeEmptyAttributes: true}}})]Copy the code

2). clean-webpack-plugin

Solve the problem: Each time you pack, you empty out what you packed before

Plugins :[// New CleanWebpackPlugin()]Copy the code

3). webpack-dev-server

Solve the problem: Help us build a backend that a Web service can do:

  • Automatic listening for code changes, changes automatically compiled
  • Automatically opens the browser rendering page
  • After recompiling, the browser is automatically refreshed to see the latest effect

Unless the configuration item is changed and needs to be re-executed, it is automatically processed.

Module. exports = {// dev-server devServer:{// port: 0, // enable gzip compress:true, Resolve (__dirname,"build"), // automatically open the browser open:true, // enable hot:true, / / proxy cross-domain proxy agent: {'/', 'http://127.0.0.1:8888'}},}Copy the code

With dev-server, the compiled results are stored in the computer’s memory, rather than in a build like the previous webpack command. Dev-server is only compiled and previewed in development mode, and the project needs to be compiled and packaged based on WebPack when it needs to be deployed

"scripts": {
    "serve": "webpack-dev-server",
    "build": "webpack"
  },
Copy the code

So in a real project there are two types of execution commands:

  • Under the development of serve, compile to memory at any time, at any time to see the effect, at any time to refresh
  • After the development, execute build, compile the content into the build folder, and upload it to the server
To enable the
{
 "scripts": {
    "serve": "webpack-dev-server"
  },
}
==> npm run serve
Copy the code

Abnormal points:

Error: Webpack-dev-server:

Error: Cannot find module ‘webpack-cli/bin/config-yargs’

The reason:

Due to webpack-cli version 4, the webpack-cli/bin/config-yargs file was deleted, and there is no config-yargs.js in the bin directory

The solution

Prompts you to download the webPack-CLI 3 version dependency

Uninstall webpack-cli NPM uninstall webpack- CLI Install webpack-cli NPM install [email protected] --save-devCopy the code

Perfect solution!

3. Import the template resource file

You can import some CSS/JS/ image files in the template

  • Self-imported files are not affected by webPack compilation (they are not compiled with files from other modules), so some common resource files are sometimes imported separately
  • Some resource libraries don’t support the CommonJs and ES6Module specifications, and such resource files can only be imported manually in the template because WebPack can’t handle them either.

Configure multi – entry package compilation

Module.exports = {// multientry entry:{index:'./ SRC /main.js', login:'./ SRC /login.js'}, Output :{// [name] Attribute name of multi-entry configuration index/login filename:'[name].[hash].min.js',},}Copy the code

Configure the multi-page template

const htmlPlugins = ['index','login'].map(item => {
    new HtmlWebpackPlugin({
        template:`./public/${item}.html`,
        filename:`${item}.html`,
        minify:{
            collapseWhitespace:true,
            removeComments:true,
            removeAttributeQuotes:true,
            removeEmptyAttributes:true
        }
    })
})

plugins:[
 ...htmlPlugins
]
Copy the code

Once you pack it up, you’ll find that every HTML file imports all the entry js files, which is not what you want, and you can configure chunks, and chunks for multiple entries.

const htmlPlugins = ['index','login'].map(item => {
    new HtmlWebpackPlugin({
        template:`./public/${item}.html`,
        filename:`${item}.html`,
        chunks:[item],   // ***
        minify:{
            collapseWhitespace:true,
            removeComments:true,
            removeAttributeQuotes:true,
            removeEmptyAttributes:true
        }
    })
})
Copy the code

The index page is displayed by default

Package the JS files separately

The common parts of multiple pages can be packaged separately.

For example, if you don’t want to merge JQ with other JS files and want to package jquery into a JS file, you can write:

 entry:{
        index:'./src/main.js',
        login:'./src/login.js',
        jquery:'jquery' // ***
    },
Copy the code

If you want to introduce jquery to both the current Index and login pages, you can do this

Const htmlPlugins = ['index','login']. Map (item => {return new HtmlWebpackPlugin({ template:`./public/${item}.html`, filename:`${item}.html`, chunks:[item,'jquery'], // *** minify:{ collapseWhitespace:true, removeComments:true, removeAttributeQuotes:true, removeEmptyAttributes:true } }) })Copy the code

In a real project, you would need to load jquery first, so you can change the order in chunks.

 chunks:['jquery', item],
Copy the code

Independent packing

If you don’t want to package it separately, you can import it in the corresponding JS file as CommonJs or ES6Module.

For example, import jquery in SRC /main.js

const $ require('jquery')
Copy the code

6. CSS resource processing

1. Loader — Style handling

1) Install less as an example

npm install css-loader style-loader less less-loader autoprefixer postcss-loader --save-dev
Copy the code
  • Css-loader: CSS loader that handles the @import/URL() syntax

  • 36. style-loader: a style loader that inserts processed CSS into a page (inline)

  • Autoprefixer postCSs-loader: automatically prefixes postcss-loader for compatibility

    If the postCSs-loader is used with autoprefixer, you need to configure additional information. Create the postcss.config.js file in the root directory and use its syntax package

    Postcss. Config. Js configuration

    module.exports = {
        plugins:[
            require('autoprefixer')
        ]
    }
    Copy the code

    Set browser compatibility (package.json)

    Github.com/browserslis… “Describes how to set the browser compatible writing.

    {"browserslist":["> 1%", // contains 99% of the browser "last 2 versions" // compatible with the latest two versions of the browser]}Copy the code
  • Less-loader: compiles less to CSS

Install sass: sass-loader node-sass

2) configuration

Module is the same as plugins

// Configure weboack loader module:{// Set rules and processing mode default execution order: From right to left, From the bottom up rules: [{/ / match which files based on the test: / \. (CSS | less) $/ I use: [" style - loader ", "CSS - loader", "postcss - loader", // "less-loader" // Options can add additional configuration {loader:"less-loader", options:{}}]}}Copy the code

2. Extract CSS: mini-CSS-extract-plugin

You can use this plugin to extract CSS content into a separate file (uncompressed) and import it as a link.

// install NPM install mini-css-extract-plugin --save-dev // import (webpack-config.js) const MiniCssExtractPlugin = // install NPM install mini-css-extract-plugin --save-dev // import (webpack-config.js) const MiniCssExtractPlugin = [new MiniCssExtractPlugin({filename:'[name].[hash].min.css'})] require('mini-css-extract ') // plugins:[new MiniCssExtractPlugin({filename:'[name].[hash].min.css'})]Copy the code

Note that the loading of MiniCssExtractPlugin is used instead of style-loader. This loader is able to separate the CSS into the directory we specify (in this case, the address of filename).

Module :{// Set rules and processing mode default execution order: From right to left, From the bottom up rules: [{/ / match which files based on the test: / \. (CSS | less) $/ I use: [/ / "style - loader", / / * * * delete style - loader MiniCssExtractPlugin. Loader / / * * *]]}}Copy the code

Running the program, you can see that CSS is introduced using link

7. Set optimization items — compress CSS/JS

1. Install

npm install optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin terser-webpack-plugin --save-dev
Copy the code

2. Introduction to the plug-in

1) CSS compression plugin: optimize- CSS -assets-webpack-plugin

2) JS compression plugin (Google) : Uglifyjs-webpack-plugin

3) JS compression plugin (commonly used) : Terser-webpack-plugin

use

// import const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') const TerserWebpackPlugin = require('terser-webpack-plugin') const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') Webpack optimization module. Exports = {/ / configuration optimization: {/ / set the compression mode minimizer: [/ / compress CSS new OptimizeCssAssetsWebpackPlugin (), // compress Js new UglifyjsWebpackPlugin({cache:true, whether to use cache parallel:true, // whether to compile sourceMap:true, // start source mapping (easy debugging)}), new TerserWebpackPlugin() ] } }Copy the code

Use one of the Js compression plug-ins.

Eight, picture processing

Where images will be used in the project:

  • CSS Sets the background image
  • Js to dynamically create images
  • Write images directly in HTML

1. Install

npm install file-loader url-loader html-withimg-loader --save-dev
Copy the code

2. Loader introduction

1) file-loader: a loader that compiles images

Handle images in CSS, JS, and font ICONS

The module: {/ / set the rules and processing mode The default execution sequence: from right to left, from bottom to top rules: [/ / picture processing {test: / \. (PNG | jpe? G | | GIF ico | BMP) $/ I, use: ['file-loader'], // *** // include:path.resolve(__dirname,' SRC '), // Exclude: / node_modules /}, / / the fonts icon Compile the picture loader {test: / \. (SVG | eot | the vera.ttf | woff | woff2) $/ I use: [" file - loader "] / / * * *},]},Copy the code

2) HTML-withimg-loader: process images in HTML pages

html

<img src=".. /src/static/image/icon.png" alt="">Copy the code

webpack.config.js

Module :{// Set the rules and processing mode default execution order: right to left, bottom to top rules:[// compile the HTML page image, the other two image processing mechanism {test: /\.html$/, use: ['html-withimg-loader'] } ] },Copy the code

3) URl-loader: Base64 conversion

When url-loader is compiled, the images that meet the conditions will be base64, and those that do not meet the conditions will continue to be processed by file-loader. Including limit conditions.

module:{ rules:[ { test: /\.(png|jpe?g|gif|ico|bmp)$/i, // use: ['file-loader'], use :[{loader:'url-loader', options:{// Base64 limit: Name: 'images/[name],[hash].[ext]', esModule:false}}]}]}Copy the code

3. Problem record

Problem: js dynamic create picture, page can not find the picture address problem.

// main.js
let image = new Image()
image.src = "./static/image/dog.jpg"
document.body.appendChild(image)
Copy the code

Analysis:

  • If the address is an extranet absolute address, you can use it directly.
  • If you need to set a relative address, you need to import the image based on require before using it, otherwise the address will not be found after compilation.

So we could write it this way

let A = require("./static/image/dog.jpg")
let image = new Image()
image.src = A
document.body.appendChild(image)
Copy the code

Nine, JS processing

ES6 conversion based on Babel

1. Install

npm install babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties @babel/plugin-transform-runtime --save-dev
Copy the code

2. Loader introduction

1) Babel-loader: Babel loader

2) @babel/core: syntax package

3) @babel/preset-env: syntax package, turn ES6 to ES5

3. Related plug-ins

Loaders can convert ES6 to ES5 syntax, but some ES6/ES7 and above cannot convert ES5 syntax directly, so some plug-ins need to be introduced.

1) @babel/plugin-proposal-decorators: class decorators

2) @babel/plugin-proposal-class-properties

This plugin converts the new syntax for class in ES7.

Class A{// ES6 constructor(){this.x =10} // ES7 static m =10}Copy the code

In ES7 we can set properties in classes (base types)

3) @babel/plugin-transform-runtime

4. Configuration

{test:/\.js$/ I, use:[{loader:'babel-loader', options:{presets:[// Turn ES6 to ES5 "@babel/preset-env"], Plugins :["@babel/plugin-proposal-decorators",{"legacy":true}], ["@babel/plugin-proposal-class-properties",{"loose":true}], "@babel/plugin-transform-runtime"]}}], Resolve (__dirname, 'SRC '), include: path.resolve(__dirname,' SRC '), // exclude: /node_modules/ /Copy the code

Continuously updated…