Webpack – Front-end resource builder, Moudle Bundler

1 Learning Objectives

  • Know what Webpack is all about, the core components
  • The main configuration file for WebPack
  • Webpack handles images, CSS precompiled languages, vUE files
  • Build a VUE project using empty folders
  • Understand webpack optimization ideas

2 What is a resource builder/packer

  • Handle JS ES6 -> ES5 Babel
  • Processing CSS LESS/SCSS -> CSS Loader
  • PNG, JPG… -> url-loader file-loader
  • A big tool to handle this –> Webpack

3 Webpack five coresOfficial document

  • Entry -> Entry Point indicates which module webpack should use

  • The output -> Output attribute tells WebPack where to export the bundles it creates and how to name those files.

  • Loader -> Webpack can only understand JavaScript and JSON files, which is a built-in capability available to WebPack out of the box. Loader enables WebPack to process other types of files and convert them into valid modules for use by applications and to be added to dependency diagrams.

  • Plugin -> Loader is used to transform certain types of modules, while plug-ins can be used to perform a wider range of tasks. Including: package optimization, resource management, injection of environment variables.

    Tip

  • Mode -> By selecting one of development, Production, or None to set the mode parameter, you can enable the optimization built into WebPack for that environment. The default value is production.

    npm i webpack webpack-cli
    Copy the code

4 processing es6

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

// .babelrc

{
  "presets": [
    "@babel/preset-env"
  ]
}
Copy the code

// webpack.config.js adds loader

{/ / regular expression match js file test: / \. Js $/, use: [{loader: 'Babel - loader,},],},Copy the code

5 Process CSS, LESS, SCSS, and SASS

npm i less-loader css-loader style-loader sass-loader
Copy the code

6 processing JPG, PNG, GIF…

npm i url-loader file-loader html-loader
Copy the code

7 HTML-webpack-plugin packages resources into HTML

npm i html-webpack-plugin
Copy the code
  • An htML-webpack-plugin without any options, which by default inserts all CSS styles extracted from the entry configuration of the Webpack into the file specified by thunk and extract-text-webpack-plugin. For example, the generated HTML file contains the following contents:

    <! DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Webpack App</title> <link href="index-af150e90583a89775c77.css" rel="stylesheet"></head> <body> <script type="text/javascript" src="common-26a14e7d42a7c7bbc4c2.js"></script> <script type="text/javascript" src="index-af150e90583a89775c77.js"></script></body> </html>Copy the code
  • Configure your own template

    New HtmlWebpackPlugin({filename: 'index.html', template: 'index.html'})],Copy the code

8 Write a Vue file to package

NPM I vue-loader vue-template-compiler@vue/compiler-sFC // v15.* NPM I vue-loader plugin "vue-loader": "^ 15.7.0", / / and the vue versions, "vue - the template - the compiler" : "^ 2.6.14", "webpack" : "^ 5.4.0", "webpack - cli" : "^3.3.12", "webpack-dev-server": "^3.11.2" // add const VueLoaderPlugin = require('vue-loader-plugin'); New HtmlWebpackPlugin({filename: 'index.html', template: 'index.html'), new VueLoaderPlugin()], // NPM error handling NPM I --legacy-peer-depsCopy the code
{test: /\. Vue $/, loader: 'vue-loader', exclude:/node_modules/},]Copy the code
  • Precautions for folder deployment of VUE

    • An error is reported if the version between packages is too high
    "Vue - loader", "^ 15.7.0", "vue" : "^ 2.6.14", "vue - the template - the compiler" : "^ 2.6.14", "webpack" : "^ 5.4.0", "webpack - cli" : "^ 3.3.12 webpack - dev -", "server" : "^ 3.11.2" "CSS - loader" : "^ 5.2.7", "HTML - webpack - plugin" : "^ 5.3.2", "SCSS" : "^ 0.2.4", "url - loader" : "^ 4.4.1", "SCSS - loader" : "^ 0.0.1", "style - loader" : "^ 3.1.0", "postcss - loader" : "^ 6.1.1 vue - loader -", "plugins" : "^ 1.3.0" "@ vue/compiler - SFC" : "^ 3.1.4", "file - loader" : "^ 6.2.0", "HTML - loader" : "^ 2.1.2",Copy the code
    • Vue -loader v15.** Need to add webpack plug-in to parse vue file
    npm i vue-loader-plugin const VueLoaderPlugin = require('vue-loader-plugin'); New HtmlWebpackPlugin({filename: 'index.html', template: 'index.html' }), new VueLoaderPlugin() ],Copy the code

9 Extract the CSS into a separate CSS file

  • NPM package download
npm i mini-css-extract-plugin -D
Copy the code
Const MiniCssExtractPlugin=require('mini-css-extract-plugin') new MiniCssExtractPlugin({// output folder and filename Filename :'static/ CSS/build.css '}), // loader configuration {// which files to match test: /\.css$/, // which loader to use for processing use: [ MiniCssExtractPlugin.loader, 'css-loader', ] },Copy the code

10 Write a Loader

  • Loader is actually a function input parameter source

    Module. Exports = function(source) {// console.log(source) return source.replace(/ I /g, 'my.exports '); }Copy the code

Write a plugin by handwebsite

  • Plugin life cycle official documentation

  • Write a HelloPlugin by hand

    • A named javascrpit function
    • Define an apply method on the prototype of the plug-in function
    • Specifies an event hook bound to WebPack itself
    • Chuliwebpack specific data for internal strength
    • The callback provided by WebPack is invoked when the functionality is complete
    class HelloPlugin {
        constructor(options) {
            this.options = options
        }
        apply(compiler){
            compiler.hooks.afterEmit.tap('HelloPlugin',compilation => {
           		 console.log('hello');
            })
        }
    }
    module.exports = HelloPlugin
    Copy the code
  • The Compiler and Compilation

    The Compiler object represents the complete Configuration of the WebPack environment. This object is created once when webPack is started, and all the actionable Settings are configured, including options, Loader, and plugin. When a plug-in is applied in a WebPack environment, the plug-in receives a reference to this Compiler object. You can use it to access the main webPack environment.

    The compilation object represents a resource version build. When running the WebPack development environment middleware, each time a file change is detected, a new compilation is created, resulting in a new set of compilation resources. A compilation object represents the current module resources, the compile-generated resources, the changing files, and the state information of the dependencies being tracked. The Compilation object also provides a number of critical timing callbacks that plug-ins can choose to use when doing custom processing.

  • Hand write an HTMLWebpackPlugin

    • Cheerio official document
    // HTML parsing HTML NPM I cheerioCopy the code
    const cheerio = require('cheerio'); const fs = require('fs'); class HTMLPlugin { constructor(options) { this.options = options } apply(compiler){ compiler.hooks.afterEmit.tap('HTMLPlugin',compilation => { // console.log(compilation.assets) let result = fs.readFileSync(this.options.template, 'utf-8'); let $= cheerio.load(result); // Object.keys(compilation.assets) Object.keys(compilation.assets).forEach(item => { if(/\.js$/.test(item)) { $(`<script  src="./${item}"></script>`).appendTo('body'); } if(/\.css$/.test(item)) { $(`<link href="./${item}" rel="stylesheet">`).appendTo('head'); } }) // console.log($.html()); fs.writeFileSync('./dist/'+this.options.filename,$.html()) }) } } module.exports = HTMLPluginCopy the code

12 webpack optimization

12.1 Production Mode packaging comes with optimization
  • tree shaking

    Remove unreferenced dead-code when packaging, which relies on import and export in the ES6 module system

  • scope hoisting

    Extrapolating the relationship between modules, merging the broken modules into a function. You can make webPack code smaller and faster

  • Code compression

    All code is compressed using the UglifyjsPlugin plug-in

12.2 CSS Extract to a separate file Mini-CSS-extract-PluginSee the 9
12.3 postCSs-loader autoprefixer Adds code prefixesThe document
npm install --save-dev postcss-loader postcss-preset-env autoprefixer
Copy the code

// postcss.config.js

Const autoprefixer = require('autoprefixer')({overrideBrowserslist: ['> 0.15% in CN']}); module.exports = { plugins: [autoprefixer] }Copy the code
12.4 Analysis package content plug-in webpack-bundle-AnalyzerThe official documentation
npm install webpack-bundle-analyzer --save-dev
Copy the code
Const BundleAnalyzerPlugin = require(' webpack-bundle-Analyzer ').BundleAnalyzerPlugin; module.exports = { plugins: [// enable BundleAnalyzerPlugin new BundleAnalyzerPlugin({// Enable port 8000 by default // Set this parameter to disabled. "webpack-bundle-analyzer --port 8123 dist/stats.json" analyzerMode: 'server', generateStatsFile: true, statsOptions: {source: false} }), ], };Copy the code
12.5 Multi-entry packaging, JS optimization, and Code Spliting increase the first-screen response speed
  • Extract the public code webPack4 + –> splitChunksPlugin plugin –webpack built-in plugin official website

    module.exports = {
        optimization: {
            splitChunks: {
                chunks: 'all'
            }
        }
    }
    Copy the code
12.6 Dynamic JS Import
  • Webpack4 + allows import syntax to be dynamically imported, requiring the plugin for Babel to support @babel/plugin-syntax-dynamic-import

    npm i -D @babel/plugin-syntax-dynamic-import
    Copy the code
    • Modify. Babelrc configuration file, add plugin, lower version browsers need to add es6.promis official documentation

      {
      "presets": ["@babel/env"],
      "plugins": [
      	"@babel/plugin-syntax-dynamic-import"
      ]
      }
      Copy the code
    • Importing imports statically requires putting imports into the top-level scope

      import $ from 'juqery'
      Copy the code
    • Dynamic import import writing method

      let a=1;
      if(a===1) {
          import('jquery').then(({ default: $ })=> {
          	// TODO:
          })
      }
      Copy the code
12.7 Improving build performance
  • NoParse website

    Prevents WebPack from parsing any files that match a given regular expression. Ignored files should not contain calls to import, require, define, or any other import mechanism. Ignoring large libraries can improve build performance.

For example, when introducing some third-party libraries, such as jquery and Bootstrap, there will be no internal dependencies of other modules. Configure noParse to skip parsing dependencies.

module: { noParse: /jquery|bootstrap/, rules: [ { test: /\.js/, use: {}, exclude: Include: path.resolve(__dirname, 'SRC '), // include: path.resolve(__dirname,' SRC '), // include: path.resolve(__dirname, 'SRC '), // resolve from these folders}]}Copy the code
  • IgnorePlugin website

    IgnorePlugin prevents import or require calls from being made for modules that match regular expressions or filter functions.

    When introducing some third-party modules, such as moment, it will do i18N internationalization processing internally, so it will contain many language packages, which takes up more space. For example, if you only use Chinese language packages, you can ignore all the language packages and introduce language packages as needed, so as to make the construction efficiency higher and the package generation file smaller

    • What is the language package that moment relies on first

      Import moment from 'moment' import 'moment/locale/zh-cn' import 'moment/locale/zh-cn' console.log(moment().subtract(6,'days').calendar())Copy the code
    • Use IgnorePlugin to ignore its dependencies

      new webpack.IgnorePlugin({
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/,
      });
      Copy the code
    • Manually import dependencies when they are needed

  • DllPlugin website

    The DllPlugin and DllReferencePlugin have somehow managed to break down bundles while dramatically increasing the speed of builds.” The term “DLL” stands for dynamically linked libraries originally introduced by Microsoft.

    This plug-in is used to create a DLL-only -bundle in a separate Webpack configuration. The plugin generates a file called manifest.json that is used to map the DllReferencePlugin to the dependencies.