What is Webpack?

  • The Webpack module packages the tool, which analyzes the dependencies between modules, processes them using Loaders, and finally generates an optimized and merged static resource.

The entry of webpack

  • You can specify an entry starting point (or multiple entry starting points) by configuring the Entry property in the Webpack configuration.
  • Single file writing
        entry: './path/to/my/entry/file.js'
Copy the code
  • Multi-file packaging (Object format)
       entry: {
        app: './src/app.js',
        vendors: './src/vendors.js'
      }
Copy the code

The output of webpack

  • Configuring the Output option controls how WebPack writes compilation files to hard disk.

    Note that even though more than one entry starting point can exist, only one output configuration can be specified, and the properties function is as follows.

  • filename
        filename:'[name].js'// The name of the exported fileCopy the code
  • path
        path:path.resolve(__dirname,'dist'// The location of the exported fileCopy the code
  • publicPath
        publicPath:'http:cdn.com.cn'// set a common header for each js file, which is http:cdn.com.cn/[name].jsCopy the code

Hot update to Webpack

1.webpack-dev-server

Don’t refresh the browser, the output file, but in the memory, use HotModuleReplacementPlugin plug-in

  • Only used in the development environment: devServer, start a Web server, the brief configuration has been and the property function is as follows
     devServer:{
            contentBase:'./dist'// Open the file directory open:true, // automatically open browser port:8010, // start proxy:{'/api':'http://localhost:30000'// reverse proxy to solve cross-domain problems}, hot:true// Automatically refresh hotOnly:true 
        },
Copy the code

2.webpack-dev-middleware

  • Transfer webAPck output files to the server, suitable for flexible customization scenarios

3. Realization of webpack hot update principle

A->B is the first compilation process. 1 -> 2 -> 3->4 is the hot update process after file changes

The mode of webpack

  • Development: Development mode, without compression code
  • Production: Production mode, which compresses code

Webpack devtool:

  • Source Map is a tool to help us debug, you can choose a Source Map format to enhance the debugging process. Different values can significantly affect the speed of build and rebuild.
  • The configuration format and some source map values are described as follows:
        devtool:'cheap-module-eval-source-map'/** * none does not indicate what is wrong *source- Map is a mapping relationship, and the location is incorrect. * Cheap -source-map improves packaging speed and only reports business code errors that are accurate to a single line * cheap-module-source-map contains business code and third-party plug-in errors are reported. The error is only down to a line *evalFastest execution, not suitable for complex code */Copy the code
  • Best practicesportal
    • The development environment
         devtool:'cheap-module-eval-source-map'.Copy the code
    • The production environment
         devtool:'cheap-module-source-map'.Copy the code

Webpack of plugins

  • Plugins are plugins that are used to power webPack functionality and, in plain English, automatically do things for you when webPack is running.

    Note: Before using plugins, remember to require() into the appropriate plugin

  • Common plugins are as follows:

  • For example:
plugins: [new CleanWebpackPlugin(), // Clean up the packing directory before each packing, such as dist. New HtmlWebpackPlugin({// An HTML file will be automatically generated after the packing, And automatically import the packaged js into the file template:'src/index.html'})].Copy the code

Webpack of loaders

  • Webpack can preprocess files using loaders. This allows you to package any static resource other than JavaScript, which is a function. Loaders there are many loaders, commonly used as follows:

  • Here are a few brief examples of common ones.

    • babel-loader

      Note: For business code development, remember to introduce the import “@babel/polyfill” in the package entry file. This is not necessary if you are developing a component library or a class library, because polyfill’s method injection is global. You can use the @babel/ plugin-transform-Runtime plugin, which will be introduced as a closure;

           { 
            test: /\.js$/, // Exclude: /\.js$/, // exclude: /\.js$/, // exclude: /\.js$/, //"babel-loader"// Use the loader name options:{// this section can also be placed in the. Babelrc file"presets": [["@babel/preset-env", {/** * specifies the version for ES6 -> ES5 */"targets": {
                      "edge": "17"."firefox": "60"."chrome": "67"."safari": "11.1"
                    },
                    "useBuiltIns": "usage"// Only convert the required business code, which can greatly reduce the packaging volume}],"@babel/preset-react"// react project]}}Copy the code
    • url-loader
      • Url-loader and file-loader function is similar, can handle images and fonts, url-loader can set smaller resources automatically base64
    {
            test:/\.(png|jpg|gif)$/,
            use:{
                loader:'url-loader', options:{/** * name: the name of the packaged image *limit: convert images smaller than 2048kb to base64 to reduce network requests. Put images larger than 2048kb into images/ * outputPath: the directory where image files are stored after packaging */ name:'[name].[ext]',
                    outputPath:'images/'.limit: 2048}}}.Copy the code
    • postcss-loader
      • Automatically add browser prefixes to CSS, such as -webkit-. It can be configured directly in Option or in postcss.config.js. The following example is configured in postcss.config.js
      module.exports = {
          plugins:[require('autoprefixer')({
              overrideBrowserslist: [
                'last 10 Chrome versions'.'last 5 Firefox versions'.'Safari >= 6'.'ie> 8']]}})Copy the code
    • css-loader
      • Css-loader is used to convert. CSS files into common.js files. Style-loader passes the style<style>The label is inserted into the head
        {
                test: /.css$/,
                use: [
                    'style-loader'//loader is called from right to left, first csS-loader, then style-loader'css-loader'] {},test: /.less$/,
                use: [
                    'style-loader'.'css-loader'.'less-loader']}}Copy the code

    File listener for Webpack

    Cons: Developers need to manually update the browser after each update

    • File monitoring is the automatic construction of new output files when changes are detected in source code
    • File listening can be done in two ways: – Start webpack command with watch parameter – set watch:true when configuring webapck.config.js
    Modeule. Export ={// The default isfalse
            watch:trueWatchOptions :{ignored:/node_modules,// Default is null. AggregateTimeout :300. // If a change is detected, aggregateTimeout will wait 300ms. 1000 // Check whether the file is changed, and the system accesses the file every 1000ms}}Copy the code

    The tree of webpack sharking

    Tree Shaking only supports the ES MOdule form. It removes code you import but don’t use, like Shaking a Tree, Shaking something you don’t need to the ground.

    • sideEffects
      • In a pure ESM module world, it’s easy to identify which files have side effects. However, our project could not achieve this purity, so it was necessary to provide hints to the Webpack compiler about what code was “pure.” For example, if we import style.css from another file, it will not be referenced in the code, but Tree Sharking will consider this to be useless code removal. At this point we can configure sideEffects in package.json to avoid style removal.
      "sideEffects": [
          "*.css"].Copy the code

    Code separation for Webpack

    • portal
    /** * runtimeChunk: code used to place associations between business code and node-modules, a very good optimization point. * Chunks: async indicates that this applies only to asynchronous code. All Indicates that this applies only to asynchronous synchronizations. * minSize is larger than this value. Number of modules loaded at the same time * maxInitialRequests: maximum number of entry files to be split * automaticNameDelimiter: the name of the packaged file connector * name:trueThe names in cacheGroups are valid * where does the code split out of cacheGroups go, such as jquery, Lodash, etc. introduced in Node-modules are packaged to vendors. Js * The larger the value of priority, the higher the precedence, Which cacheGroups and default use depends on the priority value * reuseExistingChunk: If a module is already wrapped, it is ignored */ optimization:{runtimeChunk:{name:'runtime'
        },
        usedExports:true,
        splitChunks:{
            chunks: "all"
            minSize: 30000,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                 },
             default: {
                    minChunks: 2,
                    priority: -20,
                     reuseExistingChunk: true}}}}Copy the code

    The cache of webpack

    • The [hash] substitution can be used to include a build-specific hash in the filename, But a better way is to use [chunkhash] instead and include a chunk-specific hash in the file name, so that every time the hash value of the file doesn’t change, the browser can look it up from the cache, which is very friendly to some third-party libraries.
    output:{
        filename:'[name].[contenthash].js',
        chunkFilename:'[name].[contenthash].chunk.js',
        path:path.resolve(__dirname,'.. /dist')}Copy the code

    The shimming webpack

    • The Webpack compiler recognizes modules written to ES2015 module syntax, CommonJS, or AMD specifications. However, some third-party libraries may reference global dependencies (such as $in jQuery). These libraries may also create global variables that need to be exported. These “non-conforming modules” are where Shimming comes in.
    plugins: [
       new webpack.ProvidePlugin({
       $ : 'jquery', _ :'lodash'})]Copy the code

    The alias of webpack

    • In webpack.config.js, you can configure the base path to find “commonJS/AMD modules” by setting the resolve property, set the module suffix to search for, and set the alias. Setting an alias reduces the complexity of the path where it is referenced later.
    resolve: {
       alias: {
         "@": resolve(".. /src"},},},Copy the code

    Environment variables for Webpack

    • Env is an environment variable with different values configured in package.json
    // package.json // --env.production sets env.production to when running the build commandtrue
    "scripts": {
        "dev": "webpack-dev-server --inline --config ./build/webpack.common.js"."build": "webpack --env.production --config ./build/webpack.common.js"} // webpack.exports =(env)=>{// webpack.exports =(env)=>{// webpack.exports =(env)=>{// webpack.exports =(env)=>{if(env && env.production){
            return merge(commonConfig,prodConfig)
        }else{
            return merge(commonConfig,devConfig)
        }
    }
    Copy the code

    Single page routing problem for Webpack

    • When using the HTML5 History API, any 404 response may need to be replaced with index.html. Enable by passing in the following
    historyApiFallback: true
    Copy the code

    Webpack performance optimization for packaging speed

    • Upgrade webPack or Upgrade Node, NPM, and YARN
    • Reduce the scope and use of the Loader
      rules:[
          { 
              test: /\.js$/, exclude: /node_modules/, //"babel-loader" 
          },
      Copy the code
    • Use plugins properly, using official community recommended plugins (such as code compression, which is not required by the development environment)

    Resolve for WebPack performance optimization

     resolve: {
      extensions: ['.js'.'.vue'],// You can omit.js,.vue when importing filesalias: {
        'vue$': 'vue/dist/vue.common.js'// Create an alias that can be used directly when a file is imported'src': path.resolve(__dirname, '.. /src'),
        'assets': path.resolve(__dirname, '.. /src/assets'),
        'components': path.resolve(__dirname, '.. /src/components'),
        'common': path.resolve(__dirname, '.. /src/common'),
        'img': path.resolve(__dirname, '.. /resource/img')}}Copy the code