webpack Basic Usage

Posted by rkm11 on Sun, 02 Jan 2022 15:20:24 +0100

# Basic use of webpack s
## Style Resource Introduction
import"index.css"
{
	test: /\.css$/,
	use: [
		// Create a style tag that adds style resources from js to the header and does not write directly to html, but through js execution
		'style-loader',
		// //Load css into commonjs module into js, which contains style strings
		'css-loader'
		
	]
}

file-loader, url-load for processing pictures in css and js

{
    test: /\.(png|jpg|jpeg)$/,
    use: 'url-loader',
    options: {
        // When the picture size is less than 8KB, turn the picture to Base64, which will make the picture bigger
        limit: 8 * 1024
    }
}
  • Package other resources
    Font files, such as those in css, will be changed to MD5 after packaging
{
    exclude: /\.(css|js|html)$/,
    loader: 'file-loader',
    options: {
        name: '[hash:10].[ext]'
    }
}

Separate css files
The plugin min-css-extract-plugin used needs to be MinCssExtractPlugin instead of style-loader. Loader

{
    test: /\.css$/,
    // Execution order in use is bottom to top
    use: [
        MinCssExtractPlugin.loader, // Extract css from js and separate it into separate files
        // Load the css into commonjs module into js, which contains the style string
        'css-loader',

    ]
},

new MinCssExtractPlugin({
    filename: 'public/index.css'
})

Modify css compatibility
Introducing loader, postcss-loader, and plugin postcss-preset-env in loader
Help postcss in package. Configuration found in browserlist in JSON and related configuration found on postcss's official website

{
    test: /\.css$/,
    // Execution order in use is bottom to top
    use: [
        MinCssExtractPlugin.loader, // Extract css from js and separate it into separate files
        // Load the css into commonjs module into js, which contains the style string
        'css-loader',
        {
            loader: 'postcss-loader',
            plugin: () => [
                require('postcss-preset-env')()
            ]
        }
    ]
},

package.json

  "browserlist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  }

Environment variables are not environment variables in webpack, but environment variables in node, procss.env.NODE_ENV

Compress css
Plug-ins used
optimize-css-assest-webpack-plugin
Use

new OptimizeCssAssetsWebpackPlugin()

js grammar check

Dependent on eslint-loader eslint airbnb eslint-config-airbnb-base eslint-plugin-import

To configure

{
    test: /\.js$/
    loader: "eslint-loader",
    exclude: /node_modules/
    options: {
        fix: ture // Automatically fix errors
    }
}

Rules set in package. eslintConfig in JSON
There are rules on airbnb github
Ready-made eslint-config-airbnb on npm
es6 is commonly used, so use eslint-config-airbng-base

JavaScript Compatibility Processing

Use the plug-ins babel-loader, @babel/core

Basic compatibility handling

@babel/preset-env

{
    loader: 'babel-loader',
    exclude: /node_modules/,
    options: {
        preset: ['@babel-preset-env']
    }
}

All Compatibility Processing

@babel/profill
import'@babel/profile'can be introduced in js, but it's all introduced
core-js introduced for on-demand loading

{
    loader: 'babel-loader',
    exclude: /node_modules/,
    options: {
        preset: [
            '@babel-preset-env',
            {
                useBuildIns: 'usage',
                // Specify coreJS version
                corejs: {
                    version: 3
                },
                targets: {
                    chrome: '60',
                    firefox: '60',
                    ie: '9',
                    edge: '17'
                }
            }
        ]
    }
}

Compress HTML

new HtmlWebpackPlugin({
    template: './src/index.html',
    minify: {
        //Remove spaces
        collapseWhitespace: true,
        // Remove Comments
        removeCommnets: true
    }
})

webpack performance optimization

overview

development environment

  • Packaging build speed
  • Optimize Code Debugging

production environment

  • Optimize build packing speed
  • Optimize running speed

HMR Module Thermal Replacement

A module change, a module change only updates the changed module

    devServer: {
        content: resolve(__dirname, 'build'),
        compress: true,
        port: 3000,
        // open: true,
        hot: true // Turn on HMR mode

    },

Style file, need to use style-loader, style-loader internal implementation of HMR mode
js file, not in HMR mode by default

js code needs to be modified to add functionality for HMR

if(module.hot) {
    module.hot.accept('./print.js', function() {
        console.log('loader print.js');
    });
}

HTMl file: no change

Solution introduced in entry, html changes, the whole will refresh

Debugging code source-map in development environment

In webpack. Config. Configuration under JS root object

{
    devtool: 'inline-source-map'
}
  • source-map
    Provides the exact location of error code and source code
  • inline-source-map inline to end of file
    Basic agreement with source-map, just inline
  • hidden-source-map is outlined and generated separately. Map file
    Hint error is the computer built and the cause of the error
  • eval-source-map Each produces a corresponding source-map, which is executed in the eval function
    Consistent with inline-source-map
  • Outside nosources-source-map
    Accurate information about the code was found, but no information about the source code was found
  • cheap-source-map external
    It's similar to inline, but cheap just goes to the line of code, and inline finds the exact location
  • cheap-module-source-map external
    The exact location of the error code, and the exact location of the source code, go home to loader's source-map to join

These can be combined in two groups

development environment
Speed Eval > inline > cheap
Fast

  • eval-cheap-source-map
  • eval-source-map (this is usually selected)
    Debugging friendlier
  • source-map
  • cheap-module-source-map
  • cheap-source-map

oneOf

Modify rule in webpack
Only one loader will match, colleague

{
    module: {
        rules: [
            {
                test: /\.js$/
                exclude: /node_modules/,
                enforce: 'pre', // Priority Execution
                loader: 'eslint-loader',
                options: {
                    fix: true
                }
            },
            {
                oneOf: [

                ]
            }
        ]
    }
}

// eslint-disable-next-line
Ignore warn for eslint check

cache

{
    output: {
        filename: 'build.[hash:10].js',
        path: resolve(__dirname, 'build')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new MinCssExtractPlugin({
            filename: 'public/index.[hash:10].css'
        }),
        new OptimizeCssAssetsWebpackPlgin()
    ],
}

All are rebuilt when changes occur, and the associated hash changes because js and css use the same hash
babel cache catchDireactory:true

{
    output: {
        filename: 'build.[chunkhash:10].js',
        path: resolve(__dirname, 'build')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new MinCssExtractPlugin({
            filename: 'public/index.[chunkhash:10].css'
        }),
        new OptimizeCssAssetsWebpackPlgin()
    ],
}

Rebuild all associations as well
Separate hash from file using contenthash

{
    output: {
        filename: 'build.[contenthash:10].js',
        path: resolve(__dirname, 'build')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new MinCssExtractPlugin({
            filename: 'public/index.[contenthash:10].css'
        }),
        new OptimizeCssAssetsWebpackPlgin()
    ],
}

Code Tree Shake

Prerequisites must be es6, production environment, webpack automatic tree shaking
In package. Write sideEffects: false in json, all code can be tree shaking, which will erase the css file file
sideEffects:['*.css']

Code Split

Multi-entrance

{
    entry: {
        index: './src/index.js',
        test: './src/test.js'
    },
    output: {
        filename: './js/[name].[contenthash:10].js',
        path: resolve(__dirname,'dist')
    }
}

Single entry
webpack.config.js root
Automatically analyze common files in multiple entries

optimization: {
    // Put node_ Code in modules is packaged separately into a chunk
    splitChunks: 'all'
}

Package a file into a single chunk using js

import('./simple.js').then(() => {
    console.log('load success!');
});

Lazy load

import in code

btn.onclick = () => {
    import(/* webpackChunkname: 'test'*/).then(() => {
        console.log('load success!');
    });
}

Preload

btn.onclick = () => {
    import(/* webpackChunkName: 'test', webpackPrefetch: true */).then(() => {
        console.log('load success!');
    });
}

Offline Progressive Development of PWA

Using workbox Technology
Plug-in workbox-webpack-plugin

const WorkWebpackPlugin = require('work-webpack-plugin');
{
    Plugins: [
        new WorkWebpackPlugin({
            /*
            Help service worker get started quickly, delete old service worker
            Generate a serviceworker file
            */
            clientClaim: true,
            skipWwaiting: true
        });
    ]
}

In code

if('serviceWorker' in navigater) {
    navigater.serviceWorker.register('./serviceworker.js').then(() => {
        console.log('regist successful');
    }).catch(() => {
        console.log('regist error!');
    });
}

Multiprocess Packaging

Used loader:thread-loader
Used in babel-loader

{
    test: /\.js$/
    exclude: /node_modules/,
    use: [
        'thread-loader',
        {
            loader: 'thread-loader',
            options: {
                workder: 2 // Two processes
            }
        },
        {
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
            preset: [
                '@babel-preset-env',
                {
                    useBuildIns: 'usage',
                // Specify coreJS version
                    corejs: {
                        version: 3
                    },
                    targets: {
                        chrome: '60',
                        firefox: '60',
                        ie: '9',
                        edge: '17'
                    }
                }
            ]
        }
    ]
}

There are both advantages and disadvantages
Opening also takes time, and communication between processes costs
Use only when work takes a lot of time

external

Some packages ignored when packaging
webpack.config.js root

externals: {
    // Ignore the specified package name, jquery
    jquery: 
}

dll

Package a library, third-party libraries can be packaged into different chunk s
webpack.dll.js

const { resolve } = require('path');
const webpack = require('webpack');
module.exports = {
    entry: {
        jquery: ['jquery']
    },
    output: {
        filename: '[name].js',
        path: resolve(__dirname, 'dll'),
        library: '[name]_[hash]'
    },
    plugin: [
        new webpack.DllPlugin({
            name: '[name]_[hash]', // Name of Mapping Library
            path: resolve(__name, 'dll/manifest.json') // Provide mapping relationships for jquery packages
        })
    ]
}

webpack.config.js

const webpack = require('webpack');
const addAssetsHtmlWebpackPlugin = require('add-html-webpack-plugin');
{
    plugin: [
        // Which libraries do not participate in high-speed webpack packaging and the name used will be changed
        new webpack.DllReferencPlugin({
            manifest: resolve(__dirname, 'dll/manifest.json')
        }),
        new addAssetsHtmlWebpackPlugin({
            filepath: resolve(__dirname, 'dll/jquery.js')
        });
    ]
}

Other

{
    output: {
        filename: '/js/[name].js',
        path: resolve(__dirname, 'dist'),
        publicPath: '/',
        chunkFilename: '[name]_chunk.js', // The name of the non-entry chunk,
        labraryTarget: 'window' // node commonjs
    }
}

resolve

{
    resolve: {
        alias: {
            $css: resolve(__dirname, 'src/css')
        },
        extensions: ['.js', '.json'],
        modules: [
            'node_modules',

        ]
    }
}

devServer

{
    // Project Build Catalog
    contentBase: resolve(__dirname, 'dist'),
    // Start gizp compression
    compress: true,
    // Good port
    port: 3000,
    // Open browser automatically
    open: true,
    // Turn on the HMR function,
    hot: true,
    // Monitor contentbase directory changes overload
    watchContentBase: true,
    // Do not start server logs
    clientLogLevel: 'none',
    quiet: true, // Do not print other unnecessary information
    watchOptions: {
        ignored: /node_modules/
    },
    overlay: false, // Do not prompt in full screen for errors.
    proxy: {
        '/api': {
            target: 'http://localhost:5000',
            pathRewrite: {
                '^/api': '' // Path Rewrite
            }
        }
    }
}

optimizions

const TerserWebpackPlugin = requrie('terser-webpack-plugin');
{
    optimizions: {
        splitChunk: 'all', // 
        miniSize: 30 * 1024, // Minimum split size
        maxSize: 0, // All split up,
        minChunck: 1, // Be introduced at least once
        maxAsyncRequest: 5, // Maximum number of parallel loads
        maxInitialRequest:  3, // Entry Maximum Request Parallel Number
        automaticNameDelimiter:  "~",// Named Link Rule
        name: true, // You can use it,
        cacheGroups: { // Split chunk group
            // Node_ Files in modules are packaged in vendor
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10
            },
            default: {
                // The chunk to extract is referenced at least twice
                minChunk: 2,
                priority: -20,
                // If the current module to be packaged is the same as the module already extracted, reuse does not have to be packaged
                reuseExistingChunk: true, 
            }
        },
        // Package the hash values of the current module record other modules into a single file and run ntime file
        runtimeChunk: {
            name: entrypoint=> 'runtime-${entryport.name}'
        },
        minimizer: [
            new TerserWebpackPlugin(
                cache: true, // Open Cache
                parallel: true, // Open multiprocess packaging
                sourceMap: true
            )
        ]
    }
}

Topics: Webpack