Stone sound, do not copy do not sing

The introduction

Before the advent of build tools like WebPack, front-end project construction was in the era of “high tinder”, where project code compression and obfuscations, js/ CSS dependencies and so on all had to be done manually. The emergence of Webpack solves many pain points of front-end project construction, which can be said to be a necessary part of front-end engineering.

What is a Webpack?

Webpack is a front-end project building tool that can parse project dependencies (JS/CSS/image resources, etc.) and package them.

Webpack main features:

  • The code translation
  • Merge module
  • Mixed compression
  • The code segment
  • Refreshes the
  • Automatically refresh
  • Automatic deployment

Webpack environment setup

Webpack is based on the Node environment, Node please download

Webpack installation

NPM install webpack webpack-cli -g

Partial installation (recommended) : NPM install webpack webpack-cli -d

Set up the Demo

  • Create a new basic folder and open it with Vscode
  • Local installationwebpack webpack-cli
    • npm install webpack webpack-cli -D

Webpack-cli

Webpack-cli was previously in the Webpack package, Webpack 4.0 as a separate module management.

Perform Webpack

Webpack packages projects using the Webpack directive, but this directive is only useful for globally installed Webpack. Npm5.2 provides the NPX directive, which can execute module instructions directly in a project.

The terminal executes the NPX webpack

Webpack executes, but there are dependencies and configuration issues, packaged entry, exit files, and so on that need to be configured.

Create a default entry file

The default entry file for webpack is the root directory/SRC /index.js

  • Create a new root directory/SRC /index.js

    // /src/index.js
    const init = () = > {
      console.log("Webpack is fun.")
    }
    init()
    Copy the code
  • Execute NPX webpack to successfully generate /dist/main.js

Application scenarios

Real development would involve multiple module dependency scenarios

  • New SRC/a. s

    // moduleA
    console.log("I'm module A.");
    module.exports = {
      name: "moduleA"
    }
    Copy the code
  • SRC /index.js import a.js and rebuild

    const a = require("./a")
    console.log(a.name);
    const init = () = > {
      console.log("Webpack is fun.")
    }
    init()
    Copy the code
  • Install the vscode plugin -run code and execute main.js

Execute on the browser side

Require and Module. exports belong to CommonJS modularity specification and are not supported by browsers by default. But once the code is packaged with Webpack, the modularity specification is automatically converted.

  • Create index.html (SRC /index.html) and add SRC /index.js

    <! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta Name ="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body>! - using CommonJS module specification -- -- > < script SRC = ". / index. Js "> < / script > < / body > < / HTML >Copy the code

  • Introducing the dist/main. Js

    <body> <! -- Use CommonJS modular specification --> <! --<script src="./src/index.js"></script>-- > <! -- Webpack packed js --><script src="./dist/main.js"></script>
    </body>
    Copy the code

Webpack configuration

Four core concepts of Webpack:

  • Entry: JS of a program entry
  • Output: the location where the package is stored
  • Loader: converts project dependencies and files
  • Plugin: Handles tasks that loader cannot handle

Webpack configuration file

The default Webpack configuration file name is webpack.config.js, and the configuration file must comply with the CommmonJS modularity specification.

const path = require("path")
// WebPack configuration files must follow the CommonJS specification
module.exports = {
  // Project package entry file
  entry: "./src/index.js".// Project export configuration
  output: {
    // path.resolve("path")/path.join(_dirname,"path") : Resolve relative paths to absolute paths
    path: path.resolve("./dist/"),
    // The packaged file name
    filename: 'bundle.js'
  },
  / / packaging mode (default: production) : production | | development
  mode: "development"
}
Copy the code

Webpack directive parameters

  • –config file name:

    Use a custom configuration file to execute the packaging directive: NPX webpack –config webpack.custom.config.js

    You can use different profiles for different development/live environments

  • New script instruction:

    {
      "scripts": {
         // Enter NPM run build and use webpack.custom.config.js to package
        "build": "npx webpack --config webpack.custom.config.js"}}Copy the code

HTML plugin

Webpack does not pack index.html each time it is compiled and packaged. HTML plug-ins can pack HTML files and automatically introduce other CSS/JS dependencies

HTML plugin functions 1, after packaging, automatically copy the target HTML file 2, HTML automatically import the packaged JS (note: do not manually import JS!!).

  • Install: NPM I html-webpack-plugin-d

  • Configure the plug-in in the WebPack configuration file

    // webpack.config.js
    const HtmlPlugin = require("html-webpack-plugin")
    module.exports = {
      mode: "production".// Configure the plug-in field
      plugins: [
        // Create a new HtmlPlugin instance
        new HtmlPlugin(
          {
            // Package the output file name
            filename: "index.html".// Copy the target HTML
            template: "./src/index.html"}})]Copy the code
  • Modified index. HTML

    <body> <! -- Use CommonJS modular specification --> <! --<script src="./src/index.js"></script>-- > <! -- Add new node --><ul>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
      </ul><! The htML-webpack-plugin does not need to introduce JS, it will automatically introduce you --> <! --<script src="./src/index.js"></script>-->
    </body>
    Copy the code
  • Execute the instruction NPX webpack to pack

Automatic compilation tool

After each code change, NPM Run Build is recompiled, and webPack can be automatically compiled by plug-ins or tools

  • watch mode
  • Webpack-dev-server (most recommended)
  • webpack-dev-middleware

watch mode

Webpack starts the Watch mode, monitors the changes of project files, and automatically compiles packages and outputs files when it finds modified codes.

Mode 1: Webpack – CLI package instruction added--wtachparameter

1. Package. json Added watch script

"scripts": {
  "build": "npx webpack --config webpack.custom.config.js"."watch": "npx webpack --config webpack.config.js --watch"
}
Copy the code

2. The terminal executes NPM run watch and starts to listen to project files

Mode 2: WebPack configuration file to enable the Watch mode

// webpack.config.js
module.exports = {
  / / packaging mode (default: production) : production | | development
  mode: "production".// Enable the watch mode
  watch: true
}
Copy the code

webpack-dev-server

This NPM package enables services to be started locally, generating packaged bundle.js in memory. Efficient packaging: Rebuild and refresh the page after modifying the code. Note: Webpack must be installed to use webpack-dev-server

  • 1, install,webpack-dev-servernpm i webpack-dev-server -D
  • 2,webpack-dev-serverInstructions:npx webpack-dev-server --port 3001
    • –port: specifies the service port number
    • –hot: Enables hot update
    • –open: whether to automatically open the browser to access the page
  • 3. Configure the serve script to execute the script
  "scripts": {
    "serve": "npx webpack-dev-server --port 3001 --open",}Copy the code

Of course, the Webpack-dev-server service can also be enabled through the devServer field of the Webpack configuration file

  • 1. Configure devServer
 // webpack.config.js
 module.exports = {
  // Enable the watch mode
  // watch: false,
  / / configuration webpack - dev - server
  devServer: {
    // Whether the page is automatically opened after compiling
    open: true.// Service port number
    port: 3000.// Whether to enable compression
    compress: true.// Whether to enable hot update
    hot: true.// The base path of the service
    contentBase: "./src"}}Copy the code
  • 2. Configure the dev script to execute the script
 "scripts": {
    "build": "npx webpack --config webpack.custom.config.js"."watch": "npx webpack --config webpack.config.js --watch"."serve": "npx webpack-dev-server --port 3001 --open"."dev": "npx webpack serve"
  }
Copy the code

webpack-dev-middleware

Webpack-dev-middleware uses Node’s middleware, which serves as a container for webpack-packed resources to the server. Webpack-dev-server is also implemented through this

  • Install express, webpack-dev-middleware NPM I Express webpack-dev-middleware -d

  • Create server.js in the root directory

    // Create a service and run it
    // Import the Express framework
    const express = require("express")
    / / import webpack
    const webpack = require("webpack")
    // Import middleware
    const webpackDevMiddleware = require("webpack-dev-middleware")
    // Import the WebPack configuration object
    const config = require("./webpack.config.js")
    
    
    // Create a service
    const app = express()
    const compiler = webpack(config)
    
    // App registers middleware
    app.use(webpackDevMiddleware(compiler, { publicPath: "/" }))
    
    // Listen to the service
    app.listen(3001.function () {
      console.log("Port 3000 service running");
    })
    Copy the code
  • Add the script Server and execute it

     "scripts": {
      "server": "node server.js"
    }
    Copy the code

Working with CSS files

Webpack cannot process CSS files by default, so we need to use the relevant loader to do so

  • Install css-loading NPM I CSs-loader style-loader-d

  • Configure loader in configuration file (webpack.config.js)

      // Configure various loaders
    module: {
      rules: [
        // Configure the loader to parse CSS
        {
          // Loader matches the file
          test: /\.css$/i.// Webpack calls loader from right to left
          use: ['style-loader'.'css-loader']]}},Copy the code
  • New SRC/CSS/index. The CSS

    li {
     line-height: 100px;
     background-color: red;
    }
    Copy the code
  • Webpack is not packaged. We need to import CSS files into SRC /index/js

    // src/index.js
    // Add CSS to the webpack entry file
    import style from './css/index.css'
    Copy the code
  • Run NPM run serve

Process LESS/SCSS files

CSS preprocessor webpack files can also be packaged. The following uses less as an example

  • Install the loader

    npm i less-loader -D
  • newsrc/less/index.less
    ul {
      li:nth-child(1){ background-color: pink; color: green; }}Copy the code
  • Import less in the import file
    // Add less to the webPack entry file
    import './less/index.less'
    Copy the code
  • Configuration is less – loader (webpack. Config. Js)
      // Configure various loaders
    module: {
      rules: [{test: /\.css$/i.// Webpack calls loader from right to left
          use: ['style-loader'.'css-loader']},// Configures the resolution. less related loader
        {
          test: /\.less$/i.// Webpack calls loader from right to left
          use: ['style-loader'.'css-loader'.'less-loader']]}}Copy the code
  • performnpm run serve, check the effect

Process image font files

Image and font files are also processed by Loader

webpack4

Url-loader: processes files such as images and converts them to base64. Note: Url-loader is a package of file-loader. To use url-loader, you must install the file-loader

  • The installation

    npm i fild-loader url-loader -D
  • Configure related loader (webpack.config.js)
    module: {
      rules: [
      // Configure the loader used to parse images and other files
        {
          test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|wpff2$/i.// Images larger than 16940 are automatically converted to Base64 format
          use: 'url-loader? limit=16940'
          / / using the file - loader
          // use: 'file-loader'}}]Copy the code

webpack5

Webpack5 uses built-in Asset Modules to import any other type of file. 1. Asset/Resource sends a separate file and exports the URL. This was previously implemented using file-loader. Asset /inline exports a resource’s data URI. This was previously implemented using urL-loader. Asset /source Exports the source code of the resource. This was previously implemented using raw-loader. 4. Asset automatically chooses between exporting a data URI and sending a separate file. Previously, the urL-loader was used and the resource volume limit was configured.

  • Configuration file (webpack.config.js)
    module: {
      rules: [
        // Configure the loader used to parse images and other files
        {
          test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|wpff2$/i,
          type: "asset"./ / parsing
          parser: {
            // Transfer base64 condition
            dataUrlCondition: {
              // if the value is greater than 100kb, change it to base64
              maxSize: 100.// 25kb}},generator: {
            // Output path
            // name: Use the original file name
            // hash: Adds hash characters to the file name
            // ext: Use the original extension name
            filename: 'img/[name].[hash:6][ext]'.// After the package is introduced, the file name has /img
            publicPath: '/'}}},Copy the code

Configure the Babel

Webpack parses advanced syntax through the Babel package, turning it into code that is compatible with most browsers

  • The installation

    npm install babel-loader babel-core babel-preset-env
  • configurationbable-loader(webpack. Custom. Config. Js)
    // Configure various loaders
    module: {
      rules: [
        // Parse all.js files
        {
          test: /\.js$/.// exclude files such as node_modules
          exclude: /(node_modules|bower_components)/,
          use: {
            / / use the Babel - loader
            loader: 'babel-loader'.options: {
              // Use the Babel preset
              presets: ['@babel/preset-env'}}}]}Copy the code

Process the generator using beBAL

Some of the latest syntax or syntax in the draft stage, Babel needs to use the corresponding plug-in to process.

// index.js.const zs = new Person({ name: "Zhang" })
console.log("zs", zs.name);
const init = () = > {
  console.log("Webpack is fun 123fSD")
}
init()

/ / use the generator
function* fn() {
 yield 1
 yield 2
 return 3
}
let newFn = fn()
console.log("next1:", newFn.next())
console.log("next2:", newFn.next())
Copy the code

An error will be reported after packing

  • The installationplugin-transform-runtime
    npm i @babel/plugin-transform-runtime -D
    // @babel/runtime is the core dependency of @babel/plugin-transform-runtime
    npm install --save @babel/runtime  
    Copy the code
  • Working with package configurationbabel-loader (webpack.custom.config.js)
     module: {
      rules: [{test: /\.js$/,
          exclude: /(node_modules|bower_components)/,
          use: {
            loader: 'babel-loader'.options: {
              presets: ['@babel/preset-env'].// Register the Babel plugin
              plugins: ["@babel/plugin-transform-runtime"]}}}]},Copy the code
  • npm run buildperformwebpack.custom.config.js

Babel configuration file

As a tool, Babel can have a lot to configure, and if you configure Babel in Webpack, the webPack configuration file size may be too large, poor readability, etc. You can solve this problem with Babel’s separate configuration file

.babelrc.json

Create.babelrc.json in the project root directory and transplant the options field of babel-loader to.babelrc.json.

// .babelrc.json  
{
  "presets": [
    "@babel/preset-env"]."plugins": [
    "@babel/plugin-transform-runtime"]}// webpack.custom.config.js  
      {
        test: /\.js$/.// exclude files such as node_modules
        exclude: /(node_modules|bower_components)/,
        use: {
          / / use the Babel - loader
          loader: 'babel-loader'.// Migrate to.babelrc.json
          // options: {
          // // use Babel's presets
          // presets: ['@babel/preset-env'],
          // plugins: ["@babel/plugin-transform-runtime"]
          // }}}Copy the code

Prototype methods for handling instances using Bebal

In some instances, the prototype method Babel will not be converted to low-level code, which may cause compatibility problems. Such as map, includes, and other methods of array instances.

@babel/polyfill

This is a patch for @babel/ plugin-transform-Runtime, which just needs to be installed and imported where the prototype method is used

  • The installation

    npm i @babel/polyfill -D
  • The import
    // src/index.js
    / / import polyfill
    import '@babel/polyfill'
    const arr = [1.2.3]
    console.log("Does arR contain '1'?", arr.includes(1));
    console.log(arr.map(e= > e + 2));
    ` `
    Copy the code

sourceMap

Sourcemap is essentially an information file that stores the location of the code before and after the transformation. It records the pre-transformation source location of the transformed compressed code. Webpack compresses, compilers, and converts the source code from older versions to lower versions, making the code unreadable and unable to track bugs. Sourcemap is a great way to solve this problem. Sourcemap can be used in production environments but is highly recommended!! Will cause the risk of source code leakage

devtool

Devtool is webpack configuration items, used to control the use of sourceMap way [inline – | hiddeb – | eval -] [nosources -] [being – [module -]] source – the map

source-map

Devtool: source-map is the most basic usage feature:

  • External a single sourcemap file
  • Can provide the exact location of the error code, source code error location

The sample

  • Write a bug by hand

    const a = require("./a")
    import './css/index.css'
    import './less/index.less'
    import img from './img/avatar.jpg'
    console.log(a.name);
    
    class Person {
      constructor(opt) {
        this.name = opt.name
      }
    }
    // Manually declare an error (add () to console.log()))
    const zs = new Person({ name: "Zhang" }); console.log("zs", zs.name)();
    Copy the code
  • Configuration webpack. Config. Js

    const path = require("path")
    const HtmlPlugin = require("html-webpack-plugin")
    module.exports = {
      entry: "./src/index.js".output: {
        path: path.resolve(__dirname, "./dist"),
        filename: 'bundle.js'
      },
      mode: "production".plugins: [
        new HtmlPlugin(
          {filename: "index.html".template: "./src/index.html"})].module: {
        rules: [{test: /\.css$/i,use: ['style-loader'.'css-loader'] {},test: /\.less$/i, use: ['style-loader'.'css-loader'.'less-loader'] {},test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|wpff2$/i,
            type: "asset".parser: {
              dataUrlCondition: {
                maxSize: 100.// 25kb}},generator: {
              filename: 'img/[name].[hash:6][ext]'.publicPath: '/'}}, {test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {loader: 'babel-loader'}}},// Enable source-map mode
      devtool: "source-map"
    }
    Copy the code
  • Execute NPX webpack to build the project, and generate the. Map file in dist directory

inline-source-map

Features:

  • Inlining sourcemap, fast build. Only one Sourcemap is generated
  • Can provide the exact location of the error code, source code error location

Example:

  • Change webpack.config.js to “inline-source-map” devtool

    devtool: "inline-source-map"
    Copy the code
  • Delete the dist directory and run NPX webpack to rebuild the project. Without the.map file, all sourcemap data will be embedded in bundle.js as base64

hidden-source-map

Features:

  • External sourcemap file
  • Can prompt error code error cause, no error location
  • You cannot track source code error locations, only post build error code locations

eval-source-map

Features:

  • Inlining sourcemap, each file has a corresponding source-map in eval
  • Can provide error code information, source code error location

nosources-source-map

Features:

  • External a single sourcemap file
  • Error code information can be provided without any source code information

cheap-source-map

Features:

  • External a single sourcemap file
  • Can provide error code information and source code error locations (down to line only)

cheap-module-source-map

Features:

  • External a single sourcemap file
  • Error code information and source code error locations can be provided

Development environment:

The development environment requires fast, debug-friendly speed: eval > Inline > Cheap >… Eval-cheap source-map>eval-source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map source-map Eval-source-map (commonly used by MVVM frameworks)/eval-cheap-module-source-map

The production environment

Nosource-source-map Hidden-source-map Source-map/cheap-module-source-map is recommended

clean-webpack-plugin

Webpack generates a new DIST directory every time it builds. By default, it does not empty the files under DIST. This causes some cache files to remain

  • The installation

    npm i clean-webpack-plugin -D
  • Configure the plugin
    // webpack.custom.config.js  
    const CleanWebpackPlugin = require("clean-webpack-plugin").CleanWebpackPlugin
    module.exports = {
        plugins: [
         new HtmlPlugin(
          {
            filename: "index.html".template: "./src/index.html"}),// New plug-in instance
        new CleanWebpackPlugin()
       ],
    }
    Copy the code

copy-webpack-plugin

By default, webpack packs all SRC resources, while copy-webpack-plugin packs resources outside the directory

  • The installation

    npm i copy-webpack-plugin -D
  • Configure the plugin
    // webpack.custom.config.js  
    {
      plugins: [new CopyWebpackPlugin({
        patterns: [{
          // Make a copy of the project's assets directory into dist/assets
          from: path.join(__dirname, "assets"),
          to: 'assets'}]]}})Copy the code

BannerPlugin

This is a plug-in inside WebPack that adds comments, versions, and other information to the packaged JS

  • inwebpack.custom.config.js
    / / import webpack
    const Webpack = require("webpack")
    module.exports = {
      plugins: [
         new Webpack.BannerPlugin("This is a copyright message.")]}Copy the code