I. Webpack basic configuration and use

Install the local Webpack

webapck webpack-cli -D
-d indicates that the package does not need to be typed online

// Initialize the dependencies for the installation
yarn init -y

// 5.2 Supports NPX syntax to execute webpack directly
// Default is webpack.cmd in the bin file under node_modules
npx webpack
Copy the code

2. Webpack can be configured in 0

Package tool -> Output results (JS module)

Package -> Supports JS modularity

// Execute this command to package a main.js file
npx webpack
Copy the code

A message is displayed asking you to configure mode

3. Manually configure Webpack

1. Simple example

The default configuration file name is webpack.config.js

// Webpack is written by Node, so use node to run it
const path = require('path');
// This is an exported configuration file
module.exports = {
  mode: 'development'.// Mode: production development
  entry: './src/index.js'./ / the entry
  output: { / / export
    filename: 'bundle.js'.// The packaged file name
    path: path.resolve(__dirname, 'dist') // Path (must be an absolute path), __dirname is optional}}// Result: there is a dist/bundle.js file in the root
// Can be run in a browser environment
Copy the code

Simple sample file

// src/index.js
let str = require('./a.js');
console.log(str);

// src/a.js
module.exports = 'hello';

Copy the code

The result of packing

// dist/bundle.js
(() = > {
  var __webpack_modules__ = {
    "./src/a.js": // key -> module path
    (module) = > { // value -> function
      eval(
        "module.exports = 'hello'\n\n//# sourceURL=webpack://practise/./src/a.js?"
      );
    },

    "./src/index.js":
    (__unused_webpack_module, __unused_webpack_exports, __webpack_require__) = > {
      eval(
        'let str = __webpack_require__("./src/a.js")\r\n\r\nconsole.log(str)\n\n//# sourceURL=webpack://practise/./src/index.js? '); }};// If the module is loaded, it does not need to be loaded again.
  var __webpack_module_cache__ = {};
  // Configure the require method (since require does not run in a browser)
  function __webpack_require__(moduleId) {
    var cachedModule = __webpack_module_cache__[moduleId];
    // Check whether the module is in the cache. If it is in the cache, return the module directly
    if(cachedModule ! = =undefined) {
      return cachedModule.exports;
    }
    // Install a module [key: Object]
    var module = (__webpack_module_cache__[moduleId] = {
      exports: {},});// Find the corresponding function by key and execute it
    __webpack_modules__[moduleId](module.module.exports, __webpack_require__);
    // return the corresponding module.exports
    return module.exports;
  }
  var __webpack_exports__ = __webpack_require__("./src/index.js"); // './ SRC /index.js': entry module}) ();Copy the code

2. Modify the configuration file name

If you want to change the configuration file name, such as webpack.config.my.js, then package and throw an exception

But we want to be able to find our configuration file. It can be done like this:

npx webpack --config webpack.config.my.js
Copy the code

But for convenience, we can configure it in package.json:

{
    / /...
    "scripts": {
        "build": "webpack --config webpack.config.my.js"
     }
    / /...
}
Copy the code

Run NPM run build or YARN build.

But note the following:

"scripts": {
    "build": "webpack"
}

// It is not a parameter and does not recognize the content after config
npm run build --config webpack.config.my.js
yarn build --config webpack.config.my.js // the yarn command is ok

// If you must write this way, you can use the following method
npm run build -- --config webpack.config.my.js
Copy the code

3. Local development services (via IP access)[webpack-dev-server]

webpack-dev-server

// You can use NPX webpack-dev-server to enable this function, or you can configure the script

// package.json
"scripts": {
    "dev": "webpack-dev-server"
}

// webpack.config.js
module.exports = {
    // ...
    devServer: { // Configure the development server
        port: 3000.// Port number configuration
        progress: true.// You can see the packing progress bar
        contentBase: './dist'.// points to the package directory that you want to use as a static service
        compress: true // Start gzip compression
    }
    // ...
}
Copy the code

Due to compatibility issues with webpack-dev-server, if this is not successful, you can modify the script as follows:

// package.json
"scripts": {
    "dev": "webpack serve"
}
Copy the code

4. Use templates to automatically insert scripts [html-webpack-plugin]

html-webpack-plugin

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // This is a class

module.exports = {
    // ...
    output: { / / export
        filename: 'bundle.[hash].js'.// The packaged file name, also hash to avoid caching
        // filename: 'bundle.[hash:8]
        path: path.resolve(__dirname, 'dist') // Path (must be an absolute path), __dirname is optional
    },
    plugins: [ // Array: Holds all webPack plugins
        new HtmlWebpackPlugin({
            template: './src/index.html'./ / template
            filename: 'index.html'.// The packaged file name
            minify: {
                removeAttributeQuotes: true.// Delete attribute double quotes
                collapseWhitespace: true // Fold an empty line into a single line
            },
            hash: true // To avoid caching problems, add hash stamps})]// ...
}
Copy the code

5. Style

Webpack only supports JS modules by default, so you need special treatment for CSS.

yarn add css-loader style-loader -D

yarn add less less-loader -D

.

// webpack.config.js
module.exports = {
    // ...
    module: { / / module
        rules: [ / / rules
            {
                // css-loader: parse @import syntax
                // style-loader: insert CSS into the head tag
                // Loader features: hope single
                // Only one loader is used for a string
                // Multiple Loaders require arrays
                // Loaders are executed from right to left and bottom to top by default
                // Loader can also be written as an object
                test: /\.css$/,
                use: [
                    {
                        loader: 'style-loader'.options: {
                            // insertAt: 'top' // CSS style is inserted at the top to avoid style overwriting in head
                            // insertAt is deprecated
                            insert: () = >{}}},'css-loader'] {},// Process less files
                // There is also the Sass Stylus, which has a similar treatment
                // sass -> node-sass sass-loader
                // stylus -> stylus-loader
                test: /\.less$/,
                use: [
                    {
                        loader: 'style-loader'.options: {
                            // insertAt: 'top' // CSS style is inserted at the top to avoid style overwriting in head
                            // insertAt is deprecated
                            insert: () = >{}}},'css-loader'.// parse @import syntax
                    'less-loader' // less -> css]]}}// ...
}
Copy the code

1. Separate the CSS into a separate file

mini-css-extract-plugin

yarn add mini-css-extract-plugin -D

// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    plugins: [ // Array: Holds all webPack plugins
        new MiniCssExtractPlugin({
            filename: 'main.css' // Extract the name of the CSS file})].module: { / / module
        rules: [ / / rules
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'] {},test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'.// parse @import syntax
                    'less-loader' // less -> css}]}}Copy the code

2. Automatically add the browser prefix

yarn add postcss-loader autoprefixer -D

The configuration is as follows:

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

But we need to tell Webpack that we are using autoprefixer, so we need to create a new postcss.config.js file in the root directory (the same directory as webpack.config.js) :

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

If the above does not take effect, add the following configuration to package.json:

// package.json
{
	// ...
    "browserslist": [
        "last 2 versions"."1%" >."iOS 7"."last 3 iOS versions"
    ]
    // ...
}
Copy the code

3. The CSS compression

optimize-css-assets-webpack-plugin

The configuration is as follows:

// webpack.config.js
module.exports = {
    // ...
    optimization: { / / optimization
        minimizer: [
            new OptimizeCssAssetsWebpackPlugin()
        ]
    }
    // ...
}
Copy the code

However, using this plugin will cause js to not be compressed, so another plugin must be used:

uglifyjs-webpack-plugin

// webpack.config.js
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
    // ...
    optimization: { / / optimization
        minimizer: [
            new UglifyjsWebpackPlugin({
                cache: true.// Whether to use cache
                parallel: true.// Whether the package is concurrent, you can type multiple types at the same time
                sourceMap: true // After compressing js, ES6 becomes ES6, requiring a source map
            }),
            new OptimizeCssAssetsWebpackPlugin()
        ]
    },
    // ...
}
Copy the code

6. Convert ES6 syntax

Babel

1. Basic grammar

yarn add babel-loader @babel/core @babel/preset-env -D

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.js$/,
                use: {
                    loader: 'babel-loader'.// Use babel-loader to convert ES6 to ES5
                    options: {
                        presets: [
                            '@babel/preset-env' // Convert ES6 to ES5 module}}}]}// ...
}
Copy the code

2. class

yarn add @babel/plugin-proposal-class-properties -D

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.js$/,
                use: {
                    loader: 'babel-loader'.// Use babel-loader to convert ES6 to ES5
                    options: {
                        presets: [
                            '@babel/preset-env' // Convert ES6 to ES5 module].plugins: [
                            '@babel/plugin-proposal-class-properties'}}}]}// ...
}
Copy the code

3. A decorator

yarn add @babel/plugin-proposal-decorators -D

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.js$/,
                use: {
                    loader: 'babel-loader'.// Use babel-loader to convert ES6 to ES5
                    options: {
                        presets: [
                            '@babel/preset-env' // Convert ES6 to ES5 module].plugins: [["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ["@babel/plugin-proposal-class-properties", { "loose" : true}]}}}]}// ...
}
Copy the code

4. JS syntax and verification

A package for code runtime.

1. Processing of generator and promise, etc

yarn add @babel/plugin-transform-runtime -D

yarn add @babel/runtime

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.js$/,
                use: {
                    loader: 'babel-loader'.// Use babel-loader to convert ES6 to ES5
                    options: {
                        presets: [
                            '@babel/preset-env' // Convert ES6 to ES5 module].plugins: [["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ["@babel/plugin-proposal-class-properties", { "loose" : true}]."@babel/plugin-transform-runtime"]}},include: path.resolve(__dirname, 'src'), // Include, as long as this directory under
                exclude: /node_modules/ // Exclude those under this directory}}]// ...
}
Copy the code
2. Instance methods are not parsed

Such as includes.

yarn add @babel/polyfill

3. Check the JS syntax

ESLint

yarn add eslint eslint-loader -D

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.js$/.// You can write more than one at a time
                use: {
                    loader: 'eslint-loader'.options: {
                     	enforce: 'pre' // Previous Forces execution before another loader}}}, {test: /\.js$/.// ...}}]// ...
}
Copy the code

7. Introduction of global variables (three ways)

1. expose-loader

2. ProvidePlugin

3. Introduce unpackaged (externals)

expose-loader

Expose global loader inline loader

yarn add expose-loader

Usage:

// 1
import $ from 'expose-loader? $! jquery'
console.log(window. $)// 2. Configure the method in webpack.config.js and import it
import $ from 'jquery'
// ----
module.exports = {
    // ...
    module: {
        rules: [{test: require.resolve('jquery'),
                use: 'expose-loader? $'}}]// ...
}

// 3. Configure the way to webpack.config.js
// webpack.config.js
const webpack = require('webpack');
module.exports = {
    // ...
    plugins: [
        new webpack.ProvidePlugin({ // Inject $into each module. [but then window.$can't get]
            $: 'jquery'})]// ...
}

Copy the code

Pay attention to

externals

// webpack.config.js
const webpack = require('webpack');
module.exports = {
    // ...
    externals: { // Meaning: This module is externally imported and does not need to be packaged
        jquery: '$'
    }
    // ...
}
Copy the code

8. Image processing

1. Create an Image in JS and introduce (new Image())

yarn add file-loader -D

By default, file-loader internally generates an image to the packaged directory and returns the name of the generated image

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.(jpg|png|gif|jpeg)$/,
                use: 'file-loader'}}]// ...
}
Copy the code

2. Add (background(‘ URL ‘)) to CSS

CSS – loader has been support

3. Introduce (<img src="">)

yarn add html-withimg-loader -D

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

4. Base64 image conversion

When an image is larger than a certain limit, use file-loader to produce a file. But below this limit, you can use Base64 for conversion.

You can load images without making an HTTP request.

yarn add url-loader -D

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.(jpg|png|gif|jpeg)$/,
                use: {
                    loader: 'url-loader'.options: {
                        esModule: false.limit: 100 * 1024 // If the image is less than 100K, use base64, otherwise use file-loader to generate real images}}}]}// ...
}
Copy the code

9. Pack and sort files

1. Picture catalogue

// webpack.config.js
module.exports = {
    // ...
    module: {
        rules: [{test: /\.(jpg|png|gif|jpeg)$/,
                use: {
                    loader: 'url-loader'.options: {
                        esModule: false.limit: 1.outputPath: 'img/' // Package to the img directory in the package path}}}]}// ...
}
Copy the code

But a reference is intended to refer to the file corresponding to the directory under the domain name:

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // This is a class

module.exports = {
    // ...
    output: { / / export
        filename: 'bundle.[hash:8].js'.path: path.resolve(__dirname, 'dist'),
        publicPath: 'http://127.0.0.1:5500/dist' // Add such a domain name
    }
    // ...
}
Copy the code

But if you just want to add the domain name to the image, you can do this:

// webpack.config.js
module.exports = {
    // ...
    output: { / / export
        filename: 'bundle.[hash:8].js'.path: path.resolve(__dirname, 'dist')}// ...
    module: {
        rules: [{test: /\.(jpg|png|gif|jpeg)$/,
                use: {
                    loader: 'url-loader'.options: {
                        esModule: false.limit: 1.outputPath: 'img/'.// Add such a domain name and need to concatenate the above output directory
    					publicPath: 'http://127.0.0.1:5500/dist/img'}}}]}// ...
}
Copy the code

2. Style directory

// webpack.config.js
module.exports = {
    // ...
    plugins: [ // Array: Holds all webPack plugins
        new MiniCssExtractPlugin({
            filename: 'css/main.css'})]// ...
}
Copy the code