This is the 21st day of my participation in the August Text Challenge.More challenges in August

introduce

Webpack is a front-end resource loading/packaging tool that performs static analysis based on the module dependencies of the project, and then packages these modules according to the specified rules to generate the corresponding static resources. Webpack will pack a variety of static resources JS, CSS, TS, SCSS, less, PNG files into a static file. Reduced page requests.

Initialize the project

NPM init -y: use the default template to initialize the projectCopy the code

Json, which contains common project description information: project name, version number, script command, project description, entry file, developer, product-mode library dependencies, and develop-mode library dependencies.

Note:

Dependencies: jquery, Boostrap, Vue, React, Lodash

"dependencies": {     
    "jquery""^ 3.5.1 track of"   
}
Copy the code

“DevDependencies” is used when a project needs to be packaged as a finished product, such as WebPack, Sass, Babel, etc

Install webpack

NPM I -d webpack NPM install --save-dev webpack # NPM I -d webpack cli # webpack4NPM install --save-dev webpack-cliCopy the code

Pay attention to

  1. When downloading tripartite libraries using NPM in a project, be sure to add the command parameters –save(-s) or –save-dev (-d), depending on your needs.

    • — The save directive adds the current NPM download tripartite library description to the product-mode tripartite library dependency in package.json

    • The save-dev directive adds the current NPM download tripartite library description to the development mode tripartite library dependency in package.json

  2. All third-party libraries downloaded via NPM will be stored in the current project node_modules folder, which will not be uploaded to the Github repository. Because this folder is stored in some existing third-party libraries, there is no need to waste bandwidth and time to upload these existing files. This will save time, but when users download the front-end project, the project will not run directly because the repository itself does not have node_modules (the third-party library does not exist). NPM install This command automatically downloads the third-party library dependencies required by the current project according to the product mode third-party library dependencies description and development mode third-party library dependencies description in the current project package.json file.

  3. Delete tripartite library: NPM uninstall Tripartite library name –save (use –save whether the tripartite library description is added to –save or deleted from –save-dev)

NPM UN --save jQuery NPM uninstall --save jQueryCopy the code

Basic configuration of Webpack

  • Concept: In a Webpack project you can specify how to package our project webpack.config.js file called the webpack configuration file via the webpack.config.js file (the default name). This file can set a number of configuration options to add different configuration rules to WebPack

  • Grammar:

// webpack.config.js 
module.exports = {  // common.js syntax module.exports exposes a module
    // Set the WebPack configuration options
}
Copy the code

1. The entrance to the entry

The relative path to the entry starting file when the current project is packaged with WebPack.

Entry can be written in multiple ways:

  1. Single entry string notation
module.exports = {     entry"./index.js",}Copy the code
  1. Multifile object writing
module.exports = {
    entry: {
        app1: "./src/foo.js".app2: './src/bar.js'
    } // In output filename, you can use '[name]' to obtain the key value of the corresponding file
}
Copy the code

2. The output of the output

Configuration options for the output file after Webpack is packaged, including the following two options:

  • Filename Specifies the name of the output file.
  • Path Absolute path of the output directory.
// Webpack is based on Node.js, which follows the common.js specification
var path = require('path') // The path module is the core module of Node.js that handles file paths

module.exports = {
    entry: "./index.js".output: {
        // Constant in __dirname node.js, which represents the absolute path of the current file
        path: path.resolve(__dirname, 'dist'),
        // path.resolve path concatenation API(concatenate two strings with path concatenation)
        SRC /index.js SRC \index.js to solve the problem of different operating systems having different path splices
        filename: 'main.js'}}Copy the code

3. filename

Support for template characters

  • Name When multiple files are packed, each file path corresponds to a key
  • Hash Indicates the hash encoded string of the current file
module.exports = {
    entry: {
        app1: "./src/foo.js".app2: './src/bar.js'
    },
    output: {
        path: __dirname + '/dist'.filename: '[name].[hash].js'}}Copy the code

Escape loader

Webpack can use loader to preprocess files. This allows you to package any static resources other than JavaScript.

1. css-loader

The installation

npm install --save-dev css-loader style-loader
Copy the code

Configure the loader rule specified in the WebPack Module option

var path = require('path')

module.exports = {
    entry: './src/index.js'.output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.js'
    },
    module: {
        rules: [ // Apply different rules to different files
            { // Create a rule object
                test: /\.css$/.// If the file name meets the rule specified by test, the loader below will be used to escape the file
                use: ['style-loader'.'css-loader']]}},mode: 'production'
}
Copy the code

Css-loader configuration option. Css-loader can also be configured to enhance the CSS file capability

var path = require('path')

module.exports = {
    entry: './src/index.js'.output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.js'
    },
    module: {
        rules: [{
            test: /\.css$/,

            use: ['style-loader'.// The csS-loader becomes an object and receives the options configuration to add functionality to the CSS
                {
                    loader: 'css-loader'.options: {
                        url: false.// Whether to package and compile the files specified by the URL in the CSS file. The default is true
                        // Enable style modularity, CSS will enable local scope. Even though different modules with the same name do not interfere with each other
                        modules: true}}]}}Copy the code

Note: You can enable local mode for this selector using :local (without parentheses). :global(.classname) can be used to declare an unambiguous global selector. To switch this selector to global mode, use **:global (no parentheses) **.

.box {
    width: 100px;
    height: 100px;
    background-color: red;
    background-image: url(/cat.png);
}

:global(.label) {
    color: red;
    font-weight: 700;
}

:global .box {
    color: blue;
    font-size: 17px;
}
Copy the code

2.less-loader

The installation

npm install --save-dev less-loader css-loader style-loader
Copy the code

Configure the loader rule specified in the WebPack Module option

var path = require('path')

module.exports = {
    entry: './src/index.js'.output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.js'
    },
    module: {
        rules: [{
            test: /\.less$/.// Less is compiled to CSS, and the compiled file requires CSS compilation
            use: ['style-loader'.'css-loader'.'less-loader']]}},mode: 'production'
}
Copy the code

3. sass-loader

The installation

After sass-loader is installed, you need to install Node-sass, because sass is based on Ruby development and node-sass requires Node.js to support sass environment

npm install --save-dev sass-loader node-sass css-loader style-loader
Copy the code

Configure the loader rule specified in the WebPack Module option

var path = require('path')

module.exports = {
    entry: './src/index.js'.output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.js'
    },
    module: {
        rules: [{
            test: /\.(sass|scss)$/.// With Node-sass support, sass-loader compiles SCSS files to CSS, and the compiled files need CSS compilation
            use: ['style-loader'.'css-loader'.'sass-loader']]}},mode: 'production'
}
Copy the code

4. Url – loader and file – loader

Url-loader converts files to base64 encoding

File-loader Installs a loader that encrypts the file name with MD5 encryption

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

configuration

module.exports = {
    entry: './src/index.js'.output: {
        path: __dirname + '/dist'.filename: 'app.js'
    },
    module: {
        rules: [{
                test: /\.(png|jpe? g|gif)$/,
                use: [

                    {
                        loader: 'url-loader'.options: {
                            limit: 8000
                            // All files under 8000 bytes are compiled into base64 encoding
                            If the value is larger than 8000 bytes, no processing is performed}}// Webpack reported an error when packing large images because url-loader does not process images larger than 8000 bytes
                    // No other loader is responsible for packaging these large images
                    // File loader must be installed to support large images
                    // 'file-loader' file-loader does not need to be declared in webpack rules]},]},mode: 'production'
}
Copy the code

5. babel-loader

introduce

Babel-loader is a loader specially used for js conversion in Webpack. The common application scenario is to convert ES6 to ES5 and JSX to JS.

The installation

# webpack 4.0+ babel-loader 8.0NPM install --save-dev babel-loader @babel/core # webpack3.0+ babel-loader 8.0NPM install --save-dev babel-loader babel-coreCopy the code

To escape the ES6 backward compatibility, install an ES6 backward compatible configuration module

#  babel-loader 8.0+ new version NPM install --save-dev @babel/preset-env # babel-loader8.0The following old version NPM install --save-dev babel-preset-envCopy the code

Configure ES6 to ES5

module.exports = {
    entry: './src/index.js'.output: {
        path: __dirname + '/dist'.filename: 'app.js'
    },
    mode: 'development'.module: {
        rules: [{
            test: /.js$/,
            use: [{
                loader: 'babel-loader'.options: {
                    //@babel/preset-env babel-loader Is a backward compatible configuration module of ES6
                    presets: ['@babel/preset-env']}}]}}Copy the code

Configure JSX to ES5

JSX development code developed using ES6 we can convert JSX to ES6 and then to ES5

JSX Babel support modules are required if JSX needs to be escaped

# babel-loader 8.0+ new version NPM install --save-dev @babel/preset-react # babel-loader8.0NPM install --save-dev babel-preth-reactCopy the code
module.exports = {
    entry: './src/index.js'.output: {
        path: __dirname + '/dist'.filename: 'app.js'
    },
    mode: 'development'.module: {
        rules: [{
            test: /\.js$/.// exclude Exclude files from the current rules escape
            // node_modules stores the complete products that have already been packaged by the third party library, so there is no need to repeat the packaging
            exclude: /(node_modules|bower_components)/,
            use: [{
                loader: 'babel-loader'.options: {
                    presets: ['@babel/preset-env'.'@babel/preset-react']}}]}}Copy the code

Pattern mode

The default “production” product mode can also be set to “development” development mode. In production mode the code will be compressed as.min.js. Code is not compressed in development mode.

module.exports = {
    entry: {
        app1: "./src/foo.js".app2: './src/bar.js'
    },
    output: {
        path: __dirname + '/dist'.filename: '[name].[hash].js'
    },
    mode: "development" // Can also be set to "production" compressed product mode
}
Copy the code

Plug-in Plugin

1. HtmlWebpackPlugin

A plug-in that automatically generates HTML files and introduces webpack packaging files

The installation

npm install --save-dev html-webpack-plugin
Copy the code

use

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/index.js'.output: {
        path: __dirname + '/dist'.filename: 'app.js'
    },
    plugins: [
        new HtmlWebpackPlugin()
    ]
}

// New HtmlWebpackPlugin() supports some configurations
new HtmlWebpackPlugin({
    title: 'GEC'.// Generated HTML title name, invalid when used with template
    filename: 'main.html'.// The generated HTML file name
    // minify: false, // whether to compress generated HTML true compress HTML false can also customize compression rules without compression
    minify: {
        removeAttributeQuotes: true
    }, Related configuration / / https://github.com/terser/html-minifier-terser#options-quick-referenc
    template: 'public/index.html'.// Generate an HTML file reference template
    inject: 'head' // The webpack file is inserted into the newly generated HTML
    //true(the default) is equivalent to inserting the generated file 'body' at the bottom of the body tag
    // false Does not insert
    // Insert 'head' inside the  tag
})
Copy the code

2.SplitChunksPlugin

The CommonsChunksPlugin plugin was used between WebPack 4.0 releases and replaced with SplitChunksPlugin after 4.0. This module is based on WebPack so no additional download is required

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/index.js'.output: {
        path: __dirname + '/dist'.filename: 'app.js'
    },
    module: {
        rules: [{
            test: /\.js$/.// exclude Exclude files from the current rules escape
            // node_modules stores the complete products that have already been packaged by the third party library, so there is no need to repeat the packaging
            exclude: /(node_modules|bower_components)/,
            use: [{
                loader: 'babel-loader'.options: {
                    presets: ['@babel/preset-react']}}]}},optimization: {
        // SplitChunksPlugin Basic configuration
        splitChunks: {
            chunks: "initial".// all sync Initial removes and initializes itself to match the chunk name
            minSize: 3000.// Minimum size, i.e., when the module is larger than minSize, the module will be removed
            minChunks: 1.// Minimum number of modules. When the number of modules is larger than minChunks, modules will be removed
            // maxAsyncRequests: 5, // Maximum number of asynchronous requests
            // maxInitialRequests: 3, // Minimum number of initial requests
            automaticNameDelimiter: '~'.name: true.cacheGroups: { // Cache group, which specifies the location of the module to be removed
                vendors: {
                    test: /[\\/]node_modules[\\/]/}}}},plugins: [
        new HtmlWebpackPlugin({
            title: 'GEC'.// The generated HTML title name
            filename: 'main.html'.// The generated HTML file name
            minify: {
                removeAttributeQuotes: true
            }, // Whether the generated HTML is compressed
            template: 'public/index.html'.// Generate an HTML file reference template
            inject: 'body' // The webpack file is inserted into the newly generated HTML})].mode: 'production'
}
Copy the code

3. Module hot replacement plug-in

The role is in development. Preview the modified page in real time without reloading the entire page. Save the state of the entire application when the project is loaded. Update only the changed content (the effects of this plug-in can only be used with devServer)

The plug-in is within WebPack itself. So projects with WebPack installed do not need to download

const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require("webpack") // The hot module replacement plug-in itself exists within Webpack
module.exports = {
    entry: './src/index.js'.output: {
        path: __dirname + '/dist'.filename: 'app.js'
    },
    plugins: [
        new HtmlWebpackPlugin(), // Multiple plug-ins are separated by commas in their plugins configuration
        new webpack.HotModuleReplacementPlugin()
    ]
}
Copy the code

Be sure to set the hot option to true in dev-server when using hot loading modules

Development server devServer

Install the webpack server dependency module webpack-dev-server

npm install --save-dev webpack-dev-server
Copy the code

Configure the development server

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/index.js'.output: {
        path: path.join(__dirname, "dist"),
        filename: 'app.js'
    },
    plugins: [
        new HtmlWebpackPlugin()
    ],
    devServer: { // Test server
        contentBase: path.join(__dirname, "dist"), // Project file address
        compress: true.// Whether to enable server gzip to accelerate server optimization
        host: '0.0.0.0'.// Allow local IP addresses to access the current project within the LAN
        port: 1234.// Local test server port number
        before(app) {
            // Test server middleware, can add some API interface to the current server
            app.get('/api/user'.function (req, res) {
                res.json({
                    user: "GEC"
                })
            })

            app.get('/api/data'.function (req, res) {
                res.json({
                    message: "This is a message from the server to the client."})})},proxy: { // The server proxy automatically jumps to the specified server when the path set by the proxy is requested, solving the cross-domain problem
            "/search": {
                target: 'http://musicapi.leanapp.cn/'.changeOrigin: true
                // When you request /search? 123123 when will the agent to the 'http://musicapi.leanapp.cn/search?123123'}},hot: true // Enable hot loading
    } // Note that the command to start the server is not NPX webpack.
    // Start the server directive NPX webpack-dev-server (this directive requires the webpack-dev-server library installed in the project)
}
Copy the code

Start the server

NPX webpack-dev-server --hot # This command can accept multiple parameters to enable hot loading Allow IP address access to the server automatically open browser access to the current project NPX webpack-dev-server --hot --host on successful startup0.0. 0. 0 --open
Copy the code

Now we have learned 2 directives NPX webpack/ NPX webpack-dev-server. We found that the directives are quite long and troublesome. We recommend saving these two script commands in the project configuration. Simplified startup instructions. Method to save instructions in the project’s package.json file scripts option

{
    "name": "dev_server_demo"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack"."server": "webpack-dev-server"
    },
    "keywords": []."author": ""."license": "ISC"."devDependencies": {
        "html-webpack-plugin": "^ 4.3.0"."webpack": "^ 4.44.1"."webpack-cli": "^" 3.3.12."webpack-dev-server": "^ 3.11.0"}}// Use package NPM run build equivalent to NPX webpack
NPM run server is equivalent to NPX webpack-dev-server
Copy the code