Webpack Basics _ Optimization

Webpack optimizes configuration

Development environment performance optimization

  • Optimize packaging build speed
  • Optimized code debugging

Production environment performance optimization

  • Optimize packaging build speed
  • Optimize the performance of code execution

HMR

Hot Module replacement Or hot module replacement

What it does: Changes to a module repackage only that module (not all modules), increasing build speed

Style file:

  • Can use HMR function; Because style-loader implements this function internally

Js file:

  • The HMR function is disabled by default

  • Solution: The JS code needs to be modified to add the code supporting the HMR function

  • Note: the HMR function can only handle js files that are not entry js files

    import '.. /css/iconfont.css';
    import '.. /css/a.css';
    import '.. /css/b.less';
    
    import print from './print';
    
    const add = (x, y) = > x + y;
    console.log(add(1.2));
    
    if (module.hot) {
      // Once module.hot is true, HMR is enabled -> let HMR function code take effect
      module.hot.accept('./print.js'.() = > {
       The /** * method listens for print.js changes, and if they happen, other modules will not repackage them * and will execute subsequent callbacks */
        print();
      });
    }
    Copy the code

HTML file:

  • The HMR function cannot be used by default, which will cause problems. The HTML file cannot be hot updated (there is only one HTML file in the program, so there is no need to do THE HMR function).
  • Solution: Modify the entry entry to import the HTML file

Code:

  • Modify configuration file: add property hot: true in devServer
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  'style-loader'.// Extract the CSS code to a specified file
  // MiniCssExtractPlugin.loader,
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    filename: 'js/built.js'.path: resolve(__dirname, 'build'),},module: {
    rules: [
      // CSS code handling
      {
        test: /\.css$/,
        use: [
          ...commonCSSLoader,
          // // extracts the CSS code into a specified file
          // MiniCssExtractPlugin.loader,
          // // loads the CSS into the JS
          // 'css-loader',
          / / / * *
          // * CSS compatibility processing: this operation can only be performed for CSS code
          // * postcss ->
          // * postcss-loader ->
          // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
          / / * /
          / / {
          / / / * *
          // * You need to define the browserslist configuration in package.json
          / / * /
          // loader: 'postcss-loader',
          // options: {
          // // tells it what compatibility configuration to do
          // ident: 'postcss',
          // plugins: () => [
          / / / * *
          // * Postcss plugin
          // * Help postCSS find the configuration in package.json browserslist,
          // * Load the specified CSS compatibility style through configuration
          / / * /
          // require('postcss-preset-env')()
          / /]
          / /}
          // }],}, {test: /\.less$/,
        use: [
          ...commonCSSLoader,
          // MiniCssExtractPlugin.loader,
          // 'css-loader',
          'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
      // js syntax check: normalize project code to check for common syntax errors
      {
        * eslint-loader * eslint * set check rules in eslintConfig of package.json, recommend Airbnb */
        test: /\.js$/,
        exclude: /node_modules/.// Execute this loader first
        enforce: 'pre'.loader: 'eslint-loader'.options: {
          // Automatically fixes ESLint errors
          fix: true,}}, {// PRESET handling: babel-loader, @babel/preset-env, @babel/core
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'.options: {
          // Default: tell Babel what compatibility processing to do
          presets: [[// Can only do simple syntactic compatibility processing
              '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
              {
                // Load as needed
                useBuiltIns: 'usage'.// Specify the core-js version
                corejs: {
                  version: 3,},// Specify which version of the browser is compatible with
                targets: {
                  chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],],},},// Process image resources
      {
        test: /\.(png|gif|jpg|jpeg)$/,
        loader: 'url-loader'.options: {
          // Base64 processing can be applied to images smaller than 8-12KB
          limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
          esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
      {
        test: /\.html$/.// Process img resources in HTML
        loader: 'html-loader',},// Process other resources
      {
        exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
  ],
  // mode: 'production',
  mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,}};Copy the code
  • Run instruction: webpack

source-map

A technique that provides mapping of source code to post-build code, which is great for debugging code; For example, if the code fails after the build, the mapping can trace the errors in the source code

Development environment: Faster and debug friendly

Fast (eval > inline > cheap >…)

  • eval-cheap-source-map
  • eval-source-map

More debug friendly

  • source-map
  • cheap-module-source-map
  • cheap-source-map

Summary: Eval-source-map (better debugging), eval-cheap-module-source-map (better performance)

Production environment: should source code be hidden and debug friendly

Inlining makes code bigger, so it’s not used in production

Hiding source code

  • Nosource-source-map: All hidden
  • Hidden-source-map: Hides only the source code

Debugging friendly

  • source-map
  • cheap-module-source-map

Summary: use source-map and cheap-module-source-map

  • Devtool: ‘source-map’
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  'style-loader'.// Extract the CSS code to a specified file
  // MiniCssExtractPlugin.loader,
  / question: * * * * MiniCssExtractPlugin loader current less file can not be extracted separately in the specified file * /
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    filename: 'js/built.js'.path: resolve(__dirname, 'build'),},module: {
    rules: [
      // CSS code handling
      {
        test: /\.css$/,
        use: [
          ...commonCSSLoader,
          // // extracts the CSS code into a specified file
          // MiniCssExtractPlugin.loader,
          // // loads the CSS into the JS
          // 'css-loader',
          / / / * *
          // * CSS compatibility processing: this operation can only be performed for CSS code
          // * postcss ->
          // * postcss-loader ->
          // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
          / / * /
          / / {
          / / / * *
          // * You need to define the browserslist configuration in package.json
          / / * /
          // loader: 'postcss-loader',
          // options: {
          // // tells it what compatibility configuration to do
          // ident: 'postcss',
          // plugins: () => [
          / / / * *
          // * Postcss plugin
          // * Help postCSS find the configuration in package.json browserslist,
          // * Load the specified CSS compatibility style through configuration
          / / * /
          // require('postcss-preset-env')()
          / /]
          / /}
          // }],}, {test: /\.less$/,
        use: [
          ...commonCSSLoader,
          // MiniCssExtractPlugin.loader,
          // 'css-loader',
          'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
      // js syntax check: normalize project code to check for common syntax errors
      / / {
      / / / * *
      // * only check the source code, ignoring the third source library
      // * eslint-loader
      // * eslint
      // * Set check rules in package.json eslintConfig, recommend Airbnb
      / / * /
      // test: /\.js$/,
      // exclude: /node_modules/,
      // // This loader is preferentially executed
      // enforce: 'pre',
      // loader: 'eslint-loader',
      // options: {
      // // Automatically fixes ESLint errors
      // fix: true,
      / /},
      // },
      
      / / {
      // // js Compatibility processing: babel-loader, @babel/preset-env, and @babel/core
      // test: /\.js$/,
      // exclude: /node_modules/,
      // loader: 'babel-loader',
      // options: {
      // // presets: instruct Babel to do what compatibility processing
      // presets: [
      / / /
      // // can only be used for simple syntactic compatibility
      // '@babel/preset-env',
      // // corejs can do complex syntactic compatibility processing
      / / {
      // // load on demand
      // useBuiltIns: 'usage',
      // // Specifies the core-js version
      // corejs: {
      // version: 3,
      / /},
      // // specifies which browser version is compatible
      // targets: {
      // chrome: '60',
      // firefox: '50',
      // safari: '10',
      // edge: '17',
      // ie: '9',
      / /},
      / /},
      / /,
      / /,
      / /},
      // },
      
      // Process image resources
      {
        test: /\.(png|gif|jpg|jpeg)$/,
        loader: 'url-loader'.options: {
          // Base64 processing can be applied to images smaller than 8-12KB
          limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
          esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
      {
        test: /\.html$/.// Process img resources in HTML
        loader: 'html-loader',},// Process other resources
      {
        exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
  ],
  // mode: 'production',
  mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},/ source - the map Settings: * * * * [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map * source - the map: inline * error: Error code Exact information and source code error location * inline-source-map: inline * 1. Put the generated.map file in the.js file * 2. Generate only an inline source-map file * Error message: error code exact information and source code error location * hidden-source-map (prevent source code leakage) : external * 1. Put a generated source-map file in a separate.map file * Error: error code error cause, but no error location, * cannot trace source code error, only error location of built code * eval-source-map: inline * 1. A separate source-map file is generated for each file and placed in the eval function of the.js file. Error code exact information, but without any source code information (to prevent source code leakage) * cheap-source-map: external * Error message: Exact information about error code and source code location, accurate only down to line * cheap-module-source-map: * Module will add loader source-map to * */
  // Enable the post-build code to source mapping
  devtool: 'eval-source-map' // development
  // devtool: 'source-map' // production
};
Copy the code
  • Run the command NPX webpack-dev-server

oneOf

Improve packaging build speed, prevent each type of file from being judged by the following loader once

  • Modify the configuration
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  'style-loader'.// Extract the CSS code to a specified file
  // MiniCssExtractPlugin.loader,
  / question: * * * * MiniCssExtractPlugin loader current less file can not be extracted separately in the specified file * /
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    filename: 'js/built.js'.path: resolve(__dirname, 'build'),},module: {
    rules: [{* eslint-loader * eslint * set check rules in eslintConfig of package.json, recommend Airbnb */
        test: /\.js$/,
        exclude: /node_modules/.// Execute this loader first
        enforce: 'pre'.loader: 'eslint-loader'.options: {
          // Automatically fixes ESLint errors
          fix: true,}}, {/** * oneOf: improves the speed of packing builds by preventing each type of file from being judged by the following loader at once * The loader in oneOf will only match one * note: No more than two configurations in oneOf can handle the same type of file * if they do, they need to be taken out of oneOf */
        oneOf: [
          // CSS code handling
          {
            test: /\.css$/,
            use: [
              ...commonCSSLoader,
              / * * * * /
              // // extracts the CSS code into a specified file
              // MiniCssExtractPlugin.loader,
              // // loads the CSS into the JS
              // 'css-loader',
              / / / * *
              // * CSS compatibility processing: this operation can only be performed for CSS code
              // * postcss ->
              // * postcss-loader ->
              // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
              / / * /
              / / {
              / / / * *
              // * You need to define the browserslist configuration in package.json
              / / * /
              // loader: 'postcss-loader',
              // options: {
              // // tells it what compatibility configuration to do
              // ident: 'postcss',
              // plugins: () => [
              / / / * *
              // * Postcss plugin
              // * Help postCSS find the configuration in package.json browserslist,
              // * Load the specified CSS compatibility style through configuration
              / / * /
              // require('postcss-preset-env')()
              / /]
              / /}
              // }],}, {test: /\.less$/,
            use: [
              ...commonCSSLoader,
              // MiniCssExtractPlugin.loader,
              // 'css-loader',
              'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
          // js syntax check: normalize project code to check for common syntax errors

          {
            // PRESET handling: babel-loader, @babel/preset-env, @babel/core
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'.options: {
              // Default: tell Babel what compatibility processing to do
              presets: [[// Can only do simple syntactic compatibility processing
                  '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
                  {
                    // Load as needed
                    useBuiltIns: 'usage'.// Specify the core-js version
                    corejs: {
                      version: 3,},// Specify which version of the browser is compatible with
                    targets: {
                      chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],],},},// Process image resources
          {
            test: /\.(png|gif|jpg|jpeg)$/,
            loader: 'url-loader'.options: {
              // Base64 processing can be applied to images smaller than 8-12KB
              limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
              esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
          {
            test: /\.html$/.// Process img resources in HTML
            loader: 'html-loader',},// Process other resources
          {
            exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
            loader: 'file-loader'.options: {
              name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
  ],
  // mode: 'production',
  mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},/ source - the map Settings: * * * * [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map * source - the map: inline * error: Error code Exact information and source code error location * inline-source-map: inline * 1. Put the generated.map file in the.js file * 2. Generate only an inline source-map file * Error message: error code exact information and source code error location * hidden-source-map (prevent source code leakage) : external * 1. Put a generated source-map file in a separate.map file * Error: error code error cause, but no error location, * cannot trace source code error, only error location of built code * eval-source-map: inline * 1. A separate source-map file is generated for each file and placed in the eval function of the.js file. Error code exact information, but without any source code information (to prevent source code leakage) * cheap-source-map: external * Error message: Exact information about error code and source code location, accurate only down to line * cheap-module-source-map: * Module will add loader source-map to * */
  // Enable the post-build code to source mapping
  devtool: 'eval-source-map' // development
  // devtool: 'source-map' // production
};

Copy the code

Cache – 23

Babel cache: cacheDirectory: true

The js files compiled by Babel are cached, and the cache is used for the second and subsequent package builds, and only the modified JS files are recompiled; Makes packing faster after the first time

  {
    // PRESET handling: babel-loader, @babel/preset-env, @babel/core
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader'.options: {
      // Default: tell Babel what compatibility processing to do
      presets: [[// Can only do simple syntactic compatibility processing
          '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
          {
            // Load as needed
            useBuiltIns: 'usage'.// Specify the core-js version
            corejs: {
              version: 3,},// Specify which version of the browser is compatible with
            targets: {
              chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],/** * Enable the Babel cache * on the second build, the cache will be read to speed up the build */
      cacheDirectory: true}},Copy the code
File resource cache

Hash :(question)

A unique hash value is generated each time a Webpack is built

  • Problem: Js and CSS use the same hash value; If repackaged, all caches will be invalidated (if only one file is changed)

Chunkhash :(question)

A chunk is generated for all files imported from the entry file.

Hash value generated based on chunk; If the package comes from the same chunk, the hash value is the same

  • Problem: JS and CSS have the same hash value, because CSS is extracted from JS and belongs to the same chunk

Contenthash :(solved)

The hash value is generated based on the content of the file, so different files must have different hash values

  • Once the code is online, the cache works better
Results:
  • Modifying a Configuration File
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  // 'style-loader',
  // Extract the CSS code to a specified file
  MiniCssExtractPlugin.loader,
  / question: * * * * MiniCssExtractPlugin loader current less file can not be extracted separately in the specified file * /
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    /** * Add a hash value to the file to prevent caching: [hash:8] */
    filename: 'js/built.[contenthash:8].js'.path: resolve(__dirname, 'build'),},module: {
    rules: [{* eslint-loader * eslint * set check rules in eslintConfig of package.json, recommend Airbnb */
        test: /\.js$/,
        exclude: /node_modules/.// Execute this loader first
        enforce: 'pre'.loader: 'eslint-loader'.options: {
          // Automatically fixes ESLint errors
          fix: true,}}, {/** * oneOf: improves the speed of packing builds by preventing each type of file from being judged by the following loader at once * The loader in oneOf will only match one * note: No more than two configurations in oneOf can handle the same type of file * if they do, they need to be taken out of oneOf */
        oneOf: [
          // CSS code handling
          {
            test: /\.css$/,
            use: [
              ...commonCSSLoader,
              / * * * * /
              // // extracts the CSS code into a specified file
              // MiniCssExtractPlugin.loader,
              // // loads the CSS into the JS
              // 'css-loader',
              / / / * *
              // * CSS compatibility processing: this operation can only be performed for CSS code
              // * postcss ->
              // * postcss-loader ->
              // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
              / / * /
              / / {
              / / / * *
              // * You need to define the browserslist configuration in package.json
              / / * /
              // loader: 'postcss-loader',
              // options: {
              // // tells it what compatibility configuration to do
              // ident: 'postcss',
              // plugins: () => [
              / / / * *
              // * Postcss plugin
              // * Help postCSS find the configuration in package.json browserslist,
              // * Load the specified CSS compatibility style through configuration
              / / * /
              // require('postcss-preset-env')()
              / /]
              / /}
              // }],}, {test: /\.less$/,
            use: [
              ...commonCSSLoader,
              // MiniCssExtractPlugin.loader,
              // 'css-loader',
              'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
          // js syntax check: normalize project code to check for common syntax errors

          {
            // PRESET handling: babel-loader, @babel/preset-env, @babel/core
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'.options: {
              // Default: tell Babel what compatibility processing to do
              presets: [[// Can only do simple syntactic compatibility processing
                  '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
                  {
                    // Load as needed
                    useBuiltIns: 'usage'.// Specify the core-js version
                    corejs: {
                      version: 3,},// Specify which version of the browser is compatible with
                    targets: {
                      chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],/** * Enable the Babel cache * on the second build, the cache will be read to speed up the build */
              cacheDirectory: true}},// Process image resources
          {
            test: /\.(png|gif|jpg|jpeg)$/,
            loader: 'url-loader'.options: {
              // Base64 processing can be applied to images smaller than 8-12KB
              limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
              esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
          {
            test: /\.html$/.// Process img resources in HTML
            loader: 'html-loader',},// Process other resources
          {
            exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
            loader: 'file-loader'.options: {
              name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.[contenthash:8].css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
  ],
  // mode: 'production',
  mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},/ source - the map Settings: * * * * [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map * source - the map: inline * error: Error code Exact information and source code error location * inline-source-map: inline * 1. Put the generated.map file in the.js file * 2. Generate only an inline source-map file * Error message: error code exact information and source code error location * hidden-source-map (prevent source code leakage) : external * 1. Put a generated source-map file in a separate.map file * Error: error code error cause, but no error location, * cannot trace source code error, only error location of built code * eval-source-map: inline * 1. A separate source-map file is generated for each file and placed in the eval function of the.js file. Error code exact information, but without any source code information (to prevent source code leakage) * cheap-source-map: external * Error message: Exact information about error code and source code location, accurate only down to line * cheap-module-source-map: * Module will add loader source-map to * */
  // Enable the post-build code to source mapping
  devtool: 'eval-source-map' // development
  // devtool: 'source-map' // production
};

Copy the code
  • Writing node services
// server.js
* NPM I nodemon -g * nodemon server.js or * node server.js * Access server address:  * http://localhost:3080 */
// Build with Express
const express = require('express')
// 1. Create express objects
const app = express()
// 2. Use middleware to expose the 'build' file
app.use(express.static('build', { maxAge: 1000 * 3600 }))
// 3. Start the server
app.listen(3080)
Copy the code
  • Run command: NPX webpack
  • Enable the nodeJS service: node server.js

Tree Shaking: Removing useless code from applications -24

Remove source code, downloaded third-party libraries that were introduced but not used in the project

  • Effect: Reduces code size

Prerequisites:

  1. You must use ES6 modularity
  2. Start the ‘Production’ environment

Question:

  • Configure “sideEffects” in package.json: false all code has no sideEffects
    • CSS, @babel/polyfill, etc., may be ignored and killed
    • The following configuration should be made :(to avoid some files being killed)
    // package.json
    "sideEffects": [
     "*.css"."*.less"
    ]
    Copy the code

code split

Method 1 :(not recommended)

Change the application to a multi-entry file

  // Multi-entry -> Multi-page application
  // Output the number of bundles based on the number of entries
  entry: {
    index: './src/js/index.js'.test: './src/js/test.js'
  },
Copy the code
Method 2: Use the splitChunks attribute of Optimization
  1. Package the node_modules code separately into a chunk of final output
  2. Ensure that the same third-party module imported from multiple places is packaged only once
  /** * splitChunks The node_modules code is packaged separately into a chunk and finally outputs * 2. Ensure that the same third-party module is packaged only once in multiple places */
  optimization: {
    splitChunks: {
      chunks: 'all'}},Copy the code
Method 3: Import files into a separate chunk by using the JS code import syntax
  • /* webpackChunkName: ‘test’ */ : used to name the packaged file
// index.js
/** * code split: /** * code split: */
// * webpackChunkName: 'test' */ : used to name the packaged file
import(/* webpackChunkName: 'test' */'./test')
  .then((res) = > {
    console.log('test', res)
  })
  .catch(() = > {
    console.log('File load failed! ')})Copy the code

Conclusion:

In the actual development, code segmentation is generally accomplished through the combination of mode 2 and mode 3

  • Modifying a Configuration File
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  // 'style-loader',
  // Extract the CSS code to a specified file
  MiniCssExtractPlugin.loader,
  / question: * * * * MiniCssExtractPlugin loader current less file can not be extracted separately in the specified file * /
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  // Single entry -> Single page application
  entry: './src/js/index.js'./** * code split: */
  // Multi-entry -> Multi-page application
  // Output the number of bundles based on the number of entries
  // entry: {
  // index: './src/js/index.js',
  // test: './src/js/test.js'
  // },
  output: {
    /** * Add a hash value to the file to prevent caching: [hash:8] */
    filename: 'js/[name].[contenthash:8].js'.path: resolve(__dirname, 'build'),},/** * splitChunks The node_modules code is packaged separately into a chunk and finally outputs * 2. Ensure that the same third-party module is packaged only once in multiple places */
  optimization: {
    splitChunks: {
      chunks: 'all'}},module: {
    rules: [
      / / {
      / / / * *
      // * only check the source code, ignoring the third source library
      // * eslint-loader
      // * eslint
      // * Set check rules in package.json eslintConfig, recommend Airbnb
      / / * /
      // test: /\.js$/,
      // exclude: /node_modules/,
      // // This loader is preferentially executed
      // enforce: 'pre',
      // loader: 'eslint-loader',
      // options: {
      // // Automatically fixes ESLint errors
      // fix: true,
      / /},
      // },
      {
        /** * oneOf: improves the speed of packing builds by preventing each type of file from being judged by the following loader at once * The loader in oneOf will only match one * note: No more than two configurations in oneOf can handle the same type of file * if they do, they need to be taken out of oneOf */
        oneOf: [
          // CSS code handling
          {
            test: /\.css$/,
            use: [
              ...commonCSSLoader,
              / * * * * /
              // // extracts the CSS code into a specified file
              // MiniCssExtractPlugin.loader,
              // // loads the CSS into the JS
              // 'css-loader',
              / / / * *
              // * CSS compatibility processing: this operation can only be performed for CSS code
              // * postcss ->
              // * postcss-loader ->
              // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
              / / * /
              / / {
              / / / * *
              // * You need to define the browserslist configuration in package.json
              / / * /
              // loader: 'postcss-loader',
              // options: {
              // // tells it what compatibility configuration to do
              // ident: 'postcss',
              // plugins: () => [
              / / / * *
              // * Postcss plugin
              // * Help postCSS find the configuration in package.json browserslist,
              // * Load the specified CSS compatibility style through configuration
              / / * /
              // require('postcss-preset-env')()
              / /]
              / /}
              // }],}, {test: /\.less$/,
            use: [
              ...commonCSSLoader,
              // MiniCssExtractPlugin.loader,
              // 'css-loader',
              'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
          // js syntax check: normalize project code to check for common syntax errors

          {
            // PRESET handling: babel-loader, @babel/preset-env, @babel/core
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'.options: {
              // Default: tell Babel what compatibility processing to do
              presets: [[// Can only do simple syntactic compatibility processing
                  '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
                  {
                    // Load as needed
                    useBuiltIns: 'usage'.// Specify the core-js version
                    corejs: {
                      version: 3,},// Specify which version of the browser is compatible with
                    targets: {
                      chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],/** * Enable the Babel cache * on the second build, the cache will be read to speed up the build */
              cacheDirectory: true}},// Process image resources
          {
            test: /\.(png|gif|jpg|jpeg)$/,
            loader: 'url-loader'.options: {
              // Base64 processing can be applied to images smaller than 8-12KB
              limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
              esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
          {
            test: /\.html$/.// Process img resources in HTML
            loader: 'html-loader',},// Process other resources
          {
            exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
            loader: 'file-loader'.options: {
              name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.[contenthash:8].css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
  ],
  mode: 'production'.// mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},/ source - the map Settings: * * * * [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map * source - the map: inline * error: Error code Exact information and source code error location * inline-source-map: inline * 1. Put the generated.map file in the.js file * 2. Generate only an inline source-map file * Error message: error code exact information and source code error location * hidden-source-map (prevent source code leakage) : external * 1. Put a generated source-map file in a separate.map file * Error: error code error cause, but no error location, * cannot trace source code error, only error location of built code * eval-source-map: inline * 1. A separate source-map file is generated for each file and placed in the eval function of the.js file. Error code exact information, but without any source code information (to prevent source code leakage) * cheap-source-map: external * Error message: Exact information about error code and source code location, accurate only down to line * cheap-module-source-map: * Module will add loader source-map to * */
  // Enable the post-build code to source mapping
  devtool: 'eval-source-map' // development
  // devtool: 'source-map' // production
};

Copy the code
  • index.js
import $ from 'jquery';
import print from './print';
// import { mul } from './test';

import '.. /css/iconfont.css';
import '.. /css/a.css';
import '.. /css/b.less';

/** * code split: /** * code split: */
// * webpackChunkName: 'test' */ : used to name the packaged file
import(/* webpackChunkName: 'test' */'./test')
  .then((res) = > {
    console.log('test', res)
  })
  .catch(() = > {
    console.log('File load failed! ')})const add = (x, y) = > x + y;
console.log(add(1.4));
// console.log(res.mul(1, 2));

if (module.hot) {
  // Once module.hot is true, HMR is enabled -> let HMR function code take effect
  module.hot.accept('./print.js'.() = > {
    The /** * method listens for print.js changes, and if they happen, other modules will not repackage them * and will execute subsequent callbacks */
    print();
  });
}
console.log($);

Copy the code
  • Run command: NPX webpack

Lazy loading: lazy loading of JS files -26

Using the idea of code segmentation, files to be lazily loaded into the asynchronous callback function, through the code segmentation import function to introduce the file, when the trigger condition of the asynchronous function to load the corresponding file

Note: Lazy loading is preceded by code splitting

  • Normal loading: parallel loading (loading multiple files at the same time)
    • Only six files can be loaded from the same domain name using HTTP
  • Lazy loading: files are loaded when they are in use
  • Prefetch (Is not recommended) : Load the js file webpackPrefetch: true before using it
    • The browser surreptitiously loads preloaded resources after all other resources have loaded
    • Only available on PC, ie and mobile compatibility issues
// index.js
/** * lazy loading */
document.getElementById('btn').onclick = function () {
  //.test becomes lazy
  import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test')
    .then(({ mul }) = > {
      console.log(mul(1.3))})}Copy the code

Pwa: Progressive Web development applications (offline access)

Make web page can be like app, can be accessed offline, performance is also better

Configuration:

  1. Download the workbox-webpack-plugin in webpack.config.js
    plugins: [
      /** * pwa: * 1. Help serviceworker start quickly * 2. Delete the old Serviceworker * Finally: Generate a Serviceworker profile * and register serviceWorker */ in the entry file
        new WorkboxWebpackPlugin.GenerateSW({
          clientsClaim: true.skipWaiting: true})]Copy the code
  2. Register the serviceWorker in the index.js entry file
/** * Register serviceworker: * Handle compatibility issues */
/** * problem: * 1. Eslint does not recognize global variables: window, navigator... 2. Serviceworker code must run on the server * -1. nodejs * -2. NPM I serve -g, Quickly create a server * run serve-s build, start the server, and expose all resources in the build directory as static resources */
if ('serviceWorker' in navigator) {
  // After all resources are loaded
  window.addEventListener('load'.() = > {
    navigator.serviceWorker.register('/service-worker.js')
      .then(() = > {
        console.log('sw success');
      })
      .catch(() = > {
        console.log('sw fail');
      });
  });
}

Copy the code
  1. Solve some problems:
  • eslint
 /* 1. Eslint does not recognize global variables: window, navigator... The eslintConfig env attribute */ needs to be set
  "eslintConfig": {
    "extends": "airbnb-base"."env": {
      "browser": true}},Copy the code
  • Start the server
// 2. Start the server
 /* 2. Serviceworker code must run on the server * -1. nodejs * -2. NPM I serve-g, quickly create a server * Run serve-s build, start the server, Expose all resources in the build directory as static resources */
Copy the code
  • Modifying a Configuration File
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// pwa
const WorkboxWebpackPlugin = require('workbox-webpack-plugin')

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  // 'style-loader',
  // Extract the CSS code to a specified file
  MiniCssExtractPlugin.loader,
  / question: * * * * MiniCssExtractPlugin loader current less file can not be extracted separately in the specified file * /
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    /** * Add a hash value to the file to prevent caching: [hash:8] */
    filename: 'js/built.[contenthash:8].js'.path: resolve(__dirname, 'build'),},module: {
    rules: [{* eslint-loader * eslint * set check rules in eslintConfig of package.json, recommend Airbnb */
        test: /\.js$/,
        exclude: /node_modules/.// Execute this loader first
        enforce: 'pre'.loader: 'eslint-loader'.options: {
          // Automatically fixes ESLint errors
          fix: true,}}, {/** * oneOf: improves the speed of packing builds by preventing each type of file from being judged by the following loader at once * The loader in oneOf will only match one * note: No more than two configurations in oneOf can handle the same type of file * if they do, they need to be taken out of oneOf */
        oneOf: [
          // CSS code handling
          {
            test: /\.css$/,
            use: [
              ...commonCSSLoader,
              / * * * * /
              // // extracts the CSS code into a specified file
              // MiniCssExtractPlugin.loader,
              // // loads the CSS into the JS
              // 'css-loader',
              / / / * *
              // * CSS compatibility processing: this operation can only be performed for CSS code
              // * postcss ->
              // * postcss-loader ->
              // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
              / / * /
              / / {
              / / / * *
              // * You need to define the browserslist configuration in package.json
              / / * /
              // loader: 'postcss-loader',
              // options: {
              // // tells it what compatibility configuration to do
              // ident: 'postcss',
              // plugins: () => [
              / / / * *
              // * Postcss plugin
              // * Help postCSS find the configuration in package.json browserslist,
              // * Load the specified CSS compatibility style through configuration
              / / * /
              // require('postcss-preset-env')()
              / /]
              / /}
              // }],}, {test: /\.less$/,
            use: [
              ...commonCSSLoader,
              // MiniCssExtractPlugin.loader,
              // 'css-loader',
              'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
          // js syntax check: normalize project code to check for common syntax errors

          {
            // PRESET handling: babel-loader, @babel/preset-env, @babel/core
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'.options: {
              // Default: tell Babel what compatibility processing to do
              presets: [[// Can only do simple syntactic compatibility processing
                  '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
                  {
                    // Load as needed
                    useBuiltIns: 'usage'.// Specify the core-js version
                    corejs: {
                      version: 3,},// Specify which version of the browser is compatible with
                    targets: {
                      chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],/** * Enable the Babel cache * on the second build, the cache will be read to speed up the build */
              cacheDirectory: true}},// Process image resources
          {
            test: /\.(png|gif|jpg|jpeg)$/,
            loader: 'url-loader'.options: {
              // Base64 processing can be applied to images smaller than 8-12KB
              limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
              esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
          {
            test: /\.html$/.// Process img resources in HTML
            loader: 'html-loader',},// Process other resources
          {
            exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
            loader: 'file-loader'.options: {
              name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.[contenthash:8].css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
    /** * pwa: * 1. Help serviceworker start quickly * 2. Delete the old Serviceworker * Finally: Generate a Serviceworker profile * and register serviceWorker */ in the entry file
    new WorkboxWebpackPlugin.GenerateSW({
      clientsClaim: true.skipWaiting: true})].mode: 'production'.// mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},/ source - the map Settings: * * * * [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map * source - the map: inline * error: Error code Exact information and source code error location * inline-source-map: inline * 1. Put the generated.map file in the.js file * 2. Generate only an inline source-map file * Error message: error code exact information and source code error location * hidden-source-map (prevent source code leakage) : external * 1. Put a generated source-map file in a separate.map file * Error: error code error cause, but no error location, * cannot trace source code error, only error location of built code * eval-source-map: inline * 1. A separate source-map file is generated for each file and placed in the eval function of the.js file. Error code exact information, but without any source code information (to prevent source code leakage) * cheap-source-map: external * Error message: Exact information about error code and source code location, accurate only down to line * cheap-module-source-map: * Module will add loader source-map to * */
  // Enable the post-build code to source mapping
  devtool: 'eval-source-map' // development
  // devtool: 'source-map' // production
};

Copy the code
  • Index.js entry file
import print from './print';
import { mul } from './test';

import '.. /css/iconfont.css';
import '.. /css/a.css';
import '.. /css/b.less';

const add = (x, y) = > x + y;
console.log(add(1.4));
console.log(mul(1.2));

if (module.hot) {
  // Once module.hot is true, HMR is enabled -> let HMR function code take effect
  module.hot.accept('./print.js'.() = > {
    The /** * method listens for print.js changes, and if they happen, other modules will not repackage them * and will execute subsequent callbacks */
    print();
  });
}
/** * Register serviceworker: * Handle compatibility issues */
/** * problem: * 1. Eslint does not recognize global variables: window, navigator... 2. Serviceworker code must run on the server * -1. nodejs * -2. NPM I serve -g, Quickly create a server * run serve-s build, start the server, and expose all resources in the build directory as static resources */
if ('serviceWorker' in navigator) {
  // After all resources are loaded
  window.addEventListener('load'.() = > {
    navigator.serviceWorker.register('/service-worker.js')
      .then(() = > {
        console.log('sw success');
      })
      .catch(() = > {
        console.log('sw fail');
      });
  });
}

Copy the code

Multi-process packaging

It is mainly used for babel-loader to enable multi-process packaging

Question:

  1. The process takes about 600ms to start, and there is also an overhead for process communication
  2. Multi-process packaging is required only if the work takes a long time

configuration

  • Downloading the Installation package
npm install --save-dev thread-loader
Copy the code
  • Modifying a Configuration File
// nodejs
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Separate CSS from JS into a separate file
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSS code compression
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// pwa
const WorkboxWebpackPlugin = require('workbox-webpack-plugin')

// Define the nodeJS environment variable: Determines which environment to use browserslist
// process.env.NODE_ENV = 'production'
// process.env.NODE_ENV = 'development'

/ / loader reuse
const commonCSSLoader = [
  // 'style-loader',
  // Extract the CSS code to a specified file
  MiniCssExtractPlugin.loader,
  / question: * * * * MiniCssExtractPlugin loader current less file can not be extracted separately in the specified file * /
  // Load the CSS into the js
  'css-loader'.* postCSS -> * postCSs-loader -> * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration */
  {
    /** * You need to define the browserslist configuration */ in package.json
    loader: 'postcss-loader'.options: {
      // Tell it what compatibility configuration to do
      ident: 'postcss'.plugins: () = > [
        /** * PostCSS plug-ins * help PostCSS find the configuration in package.json browserslist, * load the specified CSS compatibility styles through the configuration */
        require('postcss-preset-env'(),],},},];// commonjs
module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    /** * Add a hash value to the file to prevent caching: [hash:8] */
    filename: 'js/built.[contenthash:8].js'.path: resolve(__dirname, 'build'),},module: {
    rules: [{* eslint-loader * eslint * set check rules in eslintConfig of package.json, recommend Airbnb */
        test: /\.js$/,
        exclude: /node_modules/.// Execute this loader first
        enforce: 'pre'.loader: 'eslint-loader'.options: {
          // Automatically fixes ESLint errors
          fix: true,}}, {/** * oneOf: improves the speed of packing builds by preventing each type of file from being judged by the following loader at once * The loader in oneOf will only match one * note: No more than two configurations in oneOf can handle the same type of file * if they do, they need to be taken out of oneOf */
        oneOf: [
          // CSS code handling
          {
            test: /\.css$/,
            use: [
              ...commonCSSLoader,
              / * * * * /
              // // extracts the CSS code into a specified file
              // MiniCssExtractPlugin.loader,
              // // loads the CSS into the JS
              // 'css-loader',
              / / / * *
              // * CSS compatibility processing: this operation can only be performed for CSS code
              // * postcss ->
              // * postcss-loader ->
              // * postCSs-preset -env: Helps PostCSS recognize certain environments and load the specified configuration
              / / * /
              / / {
              / / / * *
              // * You need to define the browserslist configuration in package.json
              / / * /
              // loader: 'postcss-loader',
              // options: {
              // // tells it what compatibility configuration to do
              // ident: 'postcss',
              // plugins: () => [
              / / / * *
              // * Postcss plugin
              // * Help postCSS find the configuration in package.json browserslist,
              // * Load the specified CSS compatibility style through configuration
              / / * /
              // require('postcss-preset-env')()
              / /]
              / /}
              // }],}, {test: /\.less$/,
            use: [
              ...commonCSSLoader,
              // MiniCssExtractPlugin.loader,
              // 'css-loader',
              'less-loader',]},/** * Normally, a file can only be processed by one loader; * When a file is to be processed by multiple Loaders, you must specify the order in which the loader executes it * for the.js file as follows: esLint should be executed before bable, using the Enforce attribute */
          // js syntax check: normalize project code to check for common syntax errors

          {
            // PRESET handling: babel-loader, @babel/preset-env, @babel/core
            test: /\.js$/,
            exclude: /node_modules/,
            use: [
              /** * Enable multi-process packaging: */
              {
                loader: 'thread-loader'.options: {
                  workers: 2 // Enable only two processes. The default value is -1}}, {loader: 'babel-loader'.options: {
                  // Default: tell Babel what compatibility processing to do
                  presets: [[// Can only do simple syntactic compatibility processing
                      '@babel/preset-env'.// Corejs can do complex syntactic compatibility processing
                      {
                        // Load as needed
                        useBuiltIns: 'usage'.// Specify the core-js version
                        corejs: {
                          version: 3,},// Specify which version of the browser is compatible with
                        targets: {
                          chrome: '60'.firefox: '50'.safari: '10'.edge: '17'.ie: '9',},},],/** * Enable the Babel cache * on the second build, the cache will be read to speed up the build */
                  cacheDirectory: true}}]},// Process image resources
          {
            test: /\.(png|gif|jpg|jpeg)$/,
            loader: 'url-loader'.options: {
              // Base64 processing can be applied to images smaller than 8-12KB
              limit: 8 * 1024.// Turn off ES6 parsing and use CommonJS parsing
              esModule: false.name: '[hash:10].[ext]'.outputPath: 'imgs',}},// Process img resources in HTML
          {
            test: /\.html$/.// Process img resources in HTML
            loader: 'html-loader',},// Process other resources
          {
            exclude: /\.(html|js|css|less|png|gif|jpg|jpeg)/.// Output all other resources intact
            loader: 'file-loader'.options: {
              name: '[hash:10].[ext]'.outputPath: 'media',},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// HTML code compression
      minify: {
        collapseWhitespace: true.removeComments: true,}}),new MiniCssExtractPlugin({
      // Put the extracted CSS code into a unified file and name it
      filename: 'css/built.[contenthash:8].css',}).// CSS code compression
    new OptimizeCssAssetsWebpackPlugin(),
    /** * pwa: * 1. Help serviceworker start quickly * 2. Delete the old Serviceworker * Finally: Generate a Serviceworker profile * and register serviceWorker */ in the entry file
    // new WorkboxWebpackPlugin.GenerateSW({
    // clientsClaim: true,
    // skipWaiting: true
    // })].mode: 'production'.// mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},/ source - the map Settings: * * * * [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map * source - the map: inline * error: Error code Exact information and source code error location * inline-source-map: inline * 1. Put the generated.map file in the.js file * 2. Generate only an inline source-map file * Error message: error code exact information and source code error location * hidden-source-map (prevent source code leakage) : external * 1. Put a generated source-map file in a separate.map file * Error: error code error cause, but no error location, * cannot trace source code error, only error location of built code * eval-source-map: inline * 1. A separate source-map file is generated for each file and placed in the eval function of the.js file. Error code exact information, but without any source code information (to prevent source code leakage) * cheap-source-map: external * Error message: Exact information about error code and source code location, accurate only down to line * cheap-module-source-map: * Module will add loader source-map to * */
  // Enable the post-build code to source mapping
  devtool: 'eval-source-map' // development
  // devtool: 'source-map' // production
};

Copy the code
  • Run instruction :webpack

externals

To prevent the packaging of some third party packages into the final output, bundles like jQuery, we want to introduce through the CDN and not participate in the packaging

  • Modifying a Configuration File
// webpack.config.js
  mode: 'production'.// mode: 'development',
  /** * externals: * Adds an unpackaged third-party library */
  externals: {
    // Ignored library name -> NPM package name
    jquery: 'jQuery'
  },
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3030.open: true.// Enable HRM function
    hot: true,},Copy the code

dll

Webpack Basics _ Optimization 2