• Webpack 4.X Combat (1) : Have a comprehensive understanding of Webpack and core concepts

  • Build a simple front-end project from scratch

  • Webpack4.x Actual combat (3) : 24 points summary of enterprise SPA (1)

  • Webpack4.x actual combat (IV) : 24 points summary of enterprise SPA (ii)

I. Project description

  • This is a minimalist front-end project for beginners, as outlined below (with details)

    • Start the local service webpack-dev-server

    • Processing resource paths

    • Process CSS, SCSS, and LESS

    • Css3 attribute prefix

    • Separated CSS, compressed CSS, and purified CSS

    • Babel conversion (babel7.x)

2. Project initialization

  • Create the project root folder webpack_demo_BASIC

  • Go to the terminal and run NPM init -y

    Generate package.json file as follows

  • Initialize the project file in the following directory

    SRC/CSS /index. CSS file: CSS style file

    SRC /less/less file: less style file

    SRC/SCSS /index. SCSS file: SCSS style file

    SRC /index.html file: project HTML

    SRC /index.js file: project entry js

    .babelrc file: project Babel configuration file

    .gitignore file: Git ignores configuration files (required when using Git version control)

    Package. json file: defines the modules required for the project, as well as the configuration information for the project

    Webpack.config. js file: webpack configuration file

  • Install webPack dependencies

    NPM I [email protected] [email protected] -dCopy the code
  • Basic WebPack configuration

    // webpack.config.js file const path = require('path');
    
    
    module.exports = {
        mode: 'development', // Development mode entry:'./src/index.js'// The output file name is main.js /** * or ** entry: {* index:'./src/index.js'
         * }
        */
    
        output: {
            path: path.resolve(__dirname, 'dist'), // Output the project to the root folder dist folder filename:'[name].js'}, // loader module: {rules: []}, // plugins: []};Copy the code

Configure/generate page HTML

  • Plug-in: HTML – webpack – the plugin

    Generate page HTML from the template

    Automatically import JS and other external resource files

    Set the content of the title and mate labels

    Optimizing HTML (compression, caching, conversion, etc.)

  • The installation

    NPM [email protected] - I DCopy the code
  • configuration

    // webpack.config.js file const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    
    module.exports = {
        plugins: [
            new HtmlWebpackPlugin({
                filename: 'index.html', // file name; The default is index.html template:'./src/index.html'// Specify the template HTML file title:'11111', // HTML file title tag content inject:true, // The location where the JS script is automatically imported. The default value istrue(The default value is usually sufficient.) /* * This option has the following four values: * *true/'body'The: JS script introduces * at the bottom of the body tag'head'The: JS script introduces * at the bottom of the Bead tagfalse*/ // The following is usually configured in production modehash: true// The default value isfalseAnd has a value oftrue, HTML introduced scripts, SCSS are addedhashValue (Clear cache) // You are advised to set this parameter in the production environmenttrue
                cache: true// The default value istrueTo set cache. // You are advised to set this parameter in the production environmenttrueMinify: {// It is recommended to configure this option in production environment minifycss:true// Compress CSS minifyJS:true// zip JS minifyURLs:true, // compress URL removeComments:true// Remove the comment removeAttributeQuotes:trueCollapseWhitespace: // collapseWhitespace:trueTo remove the empty line / / removeRedundantAttributes:trueRemoveEmptyAttributes:true}})]};Copy the code
  • Configuration instructions

    • View the html-webpack-plugin configuration details

    • View htML-webpack-plugin Minify configuration details

4. Configure local services

  • Server: webpack-dev-server

    A small Node.js Express server that runs projects locally during application development

  • The installation

    NPM [email protected] - I DCopy the code
  • configuration

    // webpack.config.js file const path = require('path');
    
    module.exports = {
        devServer:{
            index: 'index.html', // the server launches the page (same as the filename option in htMl-webpack-plugin); The default value is index.html port: 3000, // Specify the port number; The default 8080 host:'localhost', // specify host; Default localhost /* * or * host:'0.0.0.0'* useLocalIp * useLocalIp * useLocalIptrue,       // browser open with your local IP
            */
    
            
            open: true// After starting the local service, the page compress is automatically opened:true// Enable gzip overlay:true// Display full screen overlay in browser when compiler error or warning; The defaultfalse
            progress: true, // Whether to output the running progress to the console; The defaultfalse
    
            contentBase: path.resolve(__dirname, 'dist'), // tell the server where to supply the content. Stats: {modules: Only if you want to serve static files // Compact terminal output (local runtime) stats: {modules:false,
                children: false,
                chunks: false,
                chunkModules: false}}};Copy the code
  • Configuration instructions

    • Webpack-dev-server detailed configuration

    • Support for hot updates: code changes detected in the project are automatically updated in the browser immediately

      Newcomers should know that hot updates are limited to project code; Webpack-related configurations do not participate in hot updates

    • Thin terminal Output

      • See the next article for more details on thin terminal output

      • You can compare the stats option and the output of the terminal when running the project locally

    • Hot replacement

      • Scenario: Recommended in the development environment

      • Benefits: partial loading page changes; Speed up development and compilation

      • See the next article for more details on hot substitution

5. Configure NPM script

  • Configure instructions in package.json to run and package projects locally

    When the terminal executes NPM run XXX, it executes the XXX instruction corresponding to script in package.json

  • Local start-up project

    • Instruction configuration

      // packgae.json file {"scripts": {
          "dev": "webpack-dev-server"}}Copy the code
    • instructions

      • --progress,--open
      {
          "scripts": {
          "dev": "webpack-dev-server --progress --open"}} // --progress represents: local start project terminal displays progress // --open represents: The browser automatically opens the page after you run the webpack-dev-server. // These two options achieve the same effect as the configuration options progress and open of the webpack-dev-server. You do not need to repeat the configurationCopy the code
      • --config
      {
          "scripts": {
              "dev": "webpack-dev-server --config webpack/config.js"/ /}}"dev": "webpack-dev-server"// If there are scenarios where you want to customize the name/path of the webpack configuration file, you can specify the webpack configuration file using --config, as shown aboveCopy the code
    • In the root directory of the project, the terminal runs the NPM run dev command to run the project locally

      Visit http://localhost:3000/

  • Packaging project

    • Instruction configuration
    // packgae.json
    
    {
      "scripts": {
        "build": "webpack"}}Copy the code
    • instructions

      • The above packaging will follow the default webpack4.X packaging mechanism

      • A future article will cover how to customize packaging

    • In the root directory of the project, the terminal can execute NPM run build to package the project and output it to the dist folder in the root directory

6. Configure resource paths

1. Resolve the path problem in the project

  • Loader: url-loader and file-loader

    Resolve path issues in projects (not limited to CSS)

    Let WebPack identify resource files such as images, videos, fonts, and so on

  • Url-loader is a superset of file-loader

    Earlier versions of url-loader encapsulate file-loader. Url-loader does not rely on file-loader to run

    To use url-loader of a later version, you need to install additional file-loader

  • File-loader difference of url-loader

    • url-loader

      Resolve path issues in the project

      Convert small volume resources into Base64

      Let WebPack identify resource files

    • file-loader

      Resolve path issues in the project

      Let WebPack identify resource files

  • Analysis of the principle of file-loader

    As we all know, Webpack packs modules into a single file, and we end up with a URL path relative to the entry HTML page, rather than the path relative to the original CSS file, which causes the image import to fail

    File-loader can parse urls in projects (not limited to CSS), copy images to corresponding paths according to configurations, and modify import paths according to rules during packaging

  • The installation

    NPM I [email protected] [email protected] -dCopy the code
  • configuration

    // webpack.config.js module.exports = {module: {rules: [{test: /\.(png|jpe? g|gif|svg)(\? . *)? $/, use: [{ loader:'url-loader',
                    options: {
                        limitIf the file size is smaller than 8192 KB, it will be converted to base64 resource name:'[name].[ext]',
                        outputPath: 'static/assets/'}}]}, {test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/, use: [{ loader:'url-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'static/assets/'}}]}, {test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/, use: [{ loader:'url-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'static/assets/'// Resource output path}}]}};Copy the code
  • instructions

    • Url-loader details

    • For example, in the options.outputPath configuration, resources are output to the static/ Assets folder in the root directory

2. Resolve the path problem in HTML

  • Loader: HTML – withimg – loader

    Resolve HTML path issues, such as img tag path issues

    Webpack recommends that all images use a background image, so by default using the IMG tag in HTML will show a path error

  • The installation

    NPM [email protected] - I DCopy the code
  • configuration

    // webpack.config.js module.exports = {module: {rules: [{test: /\.(htm|html)$/,
                 use:[{
                    loader: 'html-withimg-loader'}}}}]];Copy the code

7. Configure the CSS

1. Identify the CSS

  • loader: css-loader style-loader

    Webpack only recognizes JS files by default, and the appropriate Loader must be installed to parse packaged CSS

  • The installation

    NPM I [email protected] [email protected] -dCopy the code
  • configuration

    // webpack.config.js module.exports = {module: {rules: [{test:/\.css$/,
                use: ['style-loader'.'css-loader']}}};Copy the code

2. Identify the SCSS

  • Loader: sas-loader and Node-sass

    As a CSS precompiled language, the corresponding Loader is required for parsing

  • The installation

    NPM I [email protected] [email protected] -dCopy the code
  • configuration

    Module. exports = {module: {relus: [{// webpack.config.js file module.exports = {module: {relus: [{test: /\.scss$/,
                use: ['style-loader'.'css-loader'.'sass-loader'] // Compile order from right to left}]}};Copy the code

3. Identify less

  • Loader related: less-loader, less

    As a CSS precompiled language, the corresponding Loader is required for parsing

  • The installation

    NPM I [email protected] [email protected] -dCopy the code
  • configuration

    Module. exports = {module: {relus: [{// webpack.config.js file module.exports = {module: {relus: [{test: /\.less$/,
                use: ['style-loader'.'css-loader'.'less-loader'] // Compile order from right to left}]}};Copy the code

4. Automatically add the CSS3 attribute prefix

  • Loader: postCSs-loader, autoprefixer

    Not all browsers support the new cSS3 attributes

    -webkit, -ms, -o, -moz for browsers that are compatible with different kernels

  • The installation

    NPM I [email protected] [email protected] -dCopy the code
  • configuration

    Module. exports = {plugins: [require(postcss.config.js); // module.exports = {plugins:'autoprefixer') ({"browsers": [
                    "defaults"."not ie < 11"."last 2 versions"."1%" >."iOS 7"."last 3 iOS versions"]]}});Copy the code
    / / webpack. Config. / / js file to the CSS files in the CSS 3 prefix automatically add attribute module. Exports = {module: {rules: [{test: /\.css$/,
                use: ['style-loader'.'css-loader'.'postcss-loader']}}};Copy the code
    / / webpack. Config. Js files / / to SCSS in CSS 3 prefix automatically add attribute module. Exports = {module: {rules: [{test: /\.scss$/,
                use: ['style-loader'.'css-loader'.'postcss-loader'.'sass-loader'] // Compile order from right to left}]}};Copy the code
    / / webpack. Config. / / js file to the CSS file less prefix automatically add attribute module. Exports = {module: {rules: [{test: /\.less$/,
                use: ['style-loader'.'css-loader'.'postcss-loader'.'less-loader'] // Compile order from right to left}]}};Copy the code

5. The separation of CSS

  • Plug-in: mini – CSS – extract – the plugin

    Webpack argues that CSS should be packaged into JS to reduce the number of HTTP requests

    Some development teams, however, require a separate package of CSS

  • The installation

    NPM [email protected] - I DCopy the code
  • configuration

    // webpack.config.js file, extract CSS const MinicssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
        module: {
            rules: [{
                test: /\.css$/,
                use: [MinicssExtractPlugin.loader, 'css-loader']
            }]
        },
        
        plugins: [
            new MinicssExtractPlugin({
                filename: "static/css/[name].[hash:7].css"}})]Copy the code
    // webpack.config.js file, extract SCSS const MinicssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
        module: {
            rules: [{
                test: /\.scss$/,
                use: [MinicssExtractPlugin.loader, 'css-loader'.'sass-loader'[// add a new MinicssExtractPlugin({filename:"static/css/[name].[hash:7].css"}})]Copy the code
    // webpack.config.js file, extract less const MinicssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
        module: {
            rules: [{
                test: /\.less$/,
                use: [MinicssExtractPlugin.loader, 'css-loader'.'less-loader'[// add a new MinicssExtractPlugin({filename:"static/css/[name].[hash:7].css"}})]Copy the code
  • Resolve the path problems caused by the CSS being removed

    It is easy to extract CSS, but the attribute reference path of the extracted CSS is not the same as the HTML.

    Solution: Configure the output path of the resource file (relative path to absolute path)

    // webpack.config.js configuration filelet publicPath = ' ';
    const isProduction = false; // Whether it is a production environmentif(! isProduction) { publicPath ='http://localhost:3000/static/assets';
    } elseModule. exports = {// loadermodule: {rules: [{// set publicPath to export} module.exports = {// loadermodule: {rules: [{test: /\.(png|jpe? g|gif|svg)(\? . *)? $/, use: [{ loader:'url-loader',
                    options: {
                        limitIf the file size is smaller than 8192 KB, it will be converted to base64 resource name:'[name].[ext]',
                        outputPath: 'static/assets/', // Resource output path publicPath}}]}, {test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/, use: [{ loader:'url-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'static/assets/', // Resource output path publicPath}}]}, {test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/, use: [{ loader:'url-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'static/assets/', // Resource output path publicPath}}]}};Copy the code

6. Compress the separated CSS

  • Plug-in: optimize – CSS – assets – webpack – the plugin

    Detached CSS is not compressed even in production mode

    Use this plug-in to compress CSS

  • The installation

    NPM [email protected] - I DCopy the code
  • configuration

    // webpack.config.js file const Optimizecss = require('optimize-css-assets-webpack-plugin');
    
    
    module.exports = {
        plugins: [
            new Optimizecss()
        ]
    }
    Copy the code

7. Purify the separated CSS

  • Plugins: PurifyCSs-webpack, Purify – CSS

    CSS that is not used in a page can be cleaned up by this plug-in when it is packaged

    Limitation: Only remove useless styles from detached CSS files

  • The installation

    NPM I [email protected] [email protected] -dCopy the code
  • configuration

    // webpack.config.js const glob = require('glob');
    const PurifycssPlugin = require("purifycss-webpack");
    
    
    module.exports = {
        plugins: [
            new PurifycssPlugin({           
                paths: glob.sync(path.join(__dirname, 'src/*.html'))]}});Copy the code

Configure JS correlation

1. The Babel translation

  • An overview of the

    • Browsers differ in their ability to recognize new JavaScript syntax, apis, and extension languages

    • Babel is one of the JavaScript syntax compilers

      • It mainly converts ECMAScript 2015+ JS code into javascript code that can be recognized by lower-version browsers

      • Convert JS extensions such as JSX and TypeScript into native JS that browsers can recognize

  • The installation

    NPM I [email protected] @babel/[email protected] @babel/[email protected] @babel/[email protected] @ Babel/[email protected] [email protected] @ Babel/[email protected] - DCopy the code
  • configuration

    Here are 7 + | Babel Babel – loader 8 + related configuration

    • Method 1: Remove the Babel configuration items from the.babelrc file (recommended)

      // webpack.config.js file const path = require('path');
      
      
      module.exports = {
          module: {
              rules: [{
                  test: /\.js$/,
                  use: ['babel-loader'// Exclude: /node_modules/ / include: path.resolve(__dirname,'src') // Specify the folder to load}]}};Copy the code
      //.babelrc configuration {"presets": [["@babel/preset-env", // Recall according to preset-env {"modules": false}]],"plugins": [
              "@babel/plugin-transform-runtime", // to handle global functions and optimize Babel compilation"transform-remove-console"// Remove console dependencies when packaging (not required in development environment)],"comments": false// Remove comments from scripts when packaging}Copy the code
    • Method 2: Directly configure in the WebPack configuration item (not recommended)

      // webpack.config.js file const path = require('path');
          
      
      module.exports = {
          module: {
              rules: [{
                  test: /\.js$/,
                  use: [{
                      loader: 'babel-loader',
                      options: {
                          {
                              presets: [
                                  [
                                      "@babel/preset-env", // Recall according to preset-env {"modules": false}]], plugins: ["@babel/plugin-transform-runtime", // to handle global functions and optimize Babel compilation"transform-remove-console"// Remove console when packing], comments:false}}}], exclude: /node_modules/, // exclude: /node_modules/ include: path.resolve(__dirname,'src') // Specify the folder to load}]}};Copy the code
  • instructions

    • Babel detailed configuration

2. Compression JS

  • Webpack4. X automatically compresses JS in production mode, so there are usually few scenarios in the project where plug-ins compress JS individually

  • The following two plug-ins can compress JS

    • uglifyjs-webpack-plugin

    • webpack-parallel-uglify-plugin

Webpack configuration file

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MinicssExtractPlugin = require("mini-css-extract-plugin");
const Optimizecss = require('optimize-css-assets-webpack-plugin');
const glob = require('glob');
const PurifycssPlugin = require("purifycss-webpack");



let publicPath = ' ';
const isProduction = false; // Whether it is a production environmentif(! isProduction) { publicPath ='http://localhost:3000/static/assets';
} else {
    // 将 publicPath 设置为线上发布地址
}


module.exports = {
    mode: 'development',

    entry: {
        index: './src/index.js'
    },

    output: {
        path: path.resolve(__dirname, 'dist'), // Output the project to the root folder dist folder filename:'[name].js'// Loader module: {rules: [{test: /\.(htm|html)$/,
             use:[{
                loader: 'html-withimg-loader'}]}, {test: /\.css$/,
            use: [MinicssExtractPlugin.loader, 'css-loader'] {},test: /\.scss$/,
            use: [MinicssExtractPlugin.loader, 'css-loader'.'sass-loader'] {},test: /\.less$/,
            use: [MinicssExtractPlugin.loader, 'css-loader'.'less-loader'] {},test: /\.js$/,
            use: ['babel-loader'// Exclude: /node_modules/ / include: path.resolve(__dirname,'src') // Specify the folder to load}, {test: /\.(png|jpe? g|gif|svg)(\? . *)? $/, use: [{ loader:'url-loader',
                options: {
                    limitIf the file size is smaller than 8192 KB, it will be converted to base64 resource name:'[name].[ext]',
                    outputPath: 'static/assets/',
                    publicPath
                }
            }]
        }, {
            test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/, use: [{ loader:'url-loader',
                options: {
                    name: '[name].[ext]',
                    outputPath: 'static/assets/'}}]}, {test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/, use: [{ loader:'url-loader',
                options: {
                    name: '[name].[ext]',
                    outputPath: 'static/assets/'}}]}, // plugins: [new HtmlWebpackPlugin({filename:'index.html', // file name; The default is index.html template:'./src/index.html'// Specify template HTML file}), // Separate CSS new MinicssExtractPlugin({filename:"static/css/[name].[hash:7].css"}), // New PurifycssPlugin({paths: glob.sync(path.join(__dirname,'src/*.html')),
        })
    ],

    devServer:{
        index: 'index.html', // the server launches the page (same as the filename option in htMl-webpack-plugin); The default value is index.html host:'localhost', // specify host; Default localhost port: 3000, // specify the port number; The default 8080 open:true// After starting the local service, the page compress is automatically opened:true// Enable gzip overlay:true// Display full screen overlay in browser when compiler error or warning; The defaultfalse
        progress: true, // Whether to output the running progress to the console; The defaultfalse

        contentBase: path.resolve(__dirname, 'dist'), // tell the server where to supply the content. Stats: {modules: Only if you want to serve static files // Compact terminal output (local runtime) stats: {modules:false,
            children: false,
            chunks: false,
            chunkModules: false}}};Copy the code

P.S.

  • Friends, have any questions can leave a message, exchange together

  • Next, I will also publish a few webpack4.X actual combat articles, please pay attention to

  • I am a front-end developer keen on programming, WX: ZXvictory66