Primeros pasos con la configuración de wepack4

1. Introducción al paquete web

1.1 ¿Qué es el paquete web?

webpackEs una herramienta frontal 资源构建, un 静态模块打包器(agrupador de módulos).
Desde el punto de vista del paquete web, js/json/css/img/less/...se procesarán todos los archivos de recursos front-end ( ) 模块.
Realizará un análisis estático basado en 模块, 依赖关系empaquetará y generará los correspondientes 静态资源(bundle).

inserte la descripción de la imagen aquí

webpack comenzará desde la entrada del paquete y encontrará todas las dependencias (js/json/css/img/less/…), webpack usará estas dependencias como chunkbloques (bloques de código). Luego, convierta los distintos contenidos del archivo en el bloque de fragmentos en contenido que el navegador pueda entender: menos -> css, sintaxis es6 -> sintaxis que el navegador pueda entender... Estas transformaciones se 打包产物denominan bundle.

Chunk es una colección de módulos en el proceso de empaquetado de Webpack. Sabemos que el paquete de Webpack comienza con un archivo de entrada, que también se puede decir que es un módulo de entrada. El módulo de entrada se refiere a este otro módulo, y el módulo luego se refiere al módulo. Webpack empaqueta los módulos uno por uno a través de la relación de referencia, y estos módulos forman un Chunk.

Si tenemos varios archivos de entrada, se pueden generar varias rutas de empaquetado y una ruta formará un fragmento.

inserte la descripción de la imagen aquí

1.2 Cinco conceptos básicos de webpack

1.2.1 Entrada

入口(Entry)Indica al webpack qué archivo debe 入口起点comenzar a empaquetar y analizar la compilación 内部依赖图.

1.2.2 Salida

输出(Output)bundles 输出Indica al webpack dónde y cómo deben ir los recursos incluidos 命名.

1.2.3 Cargador

LoaderDeje que el paquete web maneje esos archivos que no son de JavaScript (el paquete web en sí solo entiende JavaScript).
El cargador convierte los recursos no reconocidos por webpack 翻译como recursos reconocidos por webpck.

1.2.4 Complementos

插件(Plugins)Se puede utilizar para realizar una gama más amplia de tareas. Los complementos van desde 打包优化y 压缩hasta la redefinición del entorno 变量.

1.2.5 Modo

模式(Mode)Una configuración que le indica a webpack que use el modo correspondiente

opciones describir características
desarrollo Establecerá el valor de process.env.NODE_ENV en DefinePlugin para el desarrollo. Habilite NamedChunksPlugin y NamedModulesPlugin. Un entorno que permite depurar el código y ejecutarlo localmente
producción Establecerá el valor de process.env.NODE_ENV en DefinePlugin a producción. Habilita FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin, UglifyJsPlugin y TerserPlugin. Permite que el código optimice el entorno de ejecución en línea.

En segundo lugar, la primera experiencia de webpack.

2.1 Configuración inicial

  1. Inicializar paquete.json

Introduzca el comando:

npm init
  1. Descargue e instale el paquete web

Introduzca el comando:

npm install webpack webpack-cli -g
npm install webpack webpack-cli -D
  • webpack-cli: La línea de comando del paquete web admite el uso de funciones del paquete web mediante el uso de instrucciones.
  • -g: instalación mundial
  • -D: instalación local

2.2 Compilar y empaquetar la aplicación

  1. crear un archivo
// index.js
import data from './data.json';
console.log(data);
function add(x, y) {
    
    
  return x + y;
}
console.log(add(1, 2));
// package.json
{
    
    
  "name": "webpack_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "dev": "webpack src/index.js -o build/built.js --mode=development",
    "pro": "webpack src/index.js -o build/built.js --mode=production"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    
    
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11"
  }
}
  1. ejecutar comando
  • Instrucciones del entorno de desarrollo:
webpack src/index.js -o build/built.js --mode=development

webpack comenzará a empaquetar ./src/index.jscomo el archivo de entrada y la salida después del empaquetado ./build/built.js. El entorno general del embalaje es 开发el medio ambiente.

  • Instrucciones del entorno de producción:
webpack src/index.js -o build/built.js --mode=production

webpack comenzará a empaquetar ./src/index.jscomo el archivo de entrada y la salida después del empaquetado ./build/built.js. El entorno general del embalaje es 生产el medio ambiente.

  1. en conclusión
  • webpack puede compilar js 和 jsonarchivos empaquetados.
  • Una sintaxis que convierte la sintaxis modular de es6 浏览器能识别.
  • El entorno de producción tiene un código más que el entorno de desarrollo 压缩js.
  1. pregunta
  • css、imgLos archivos como los paquetes no se pueden compilar .
  • No se pudo js 的 es6convertir la sintaxis base a es5 以下语法.

3. Configuración básica del entorno de desarrollo de paquetes web

3.1 Crear un archivo de configuración

  1. crear un archivo
  • webpack.config.js: archivo de configuración para webpack
  • Rol: Indique al paquete web qué hacer (cuando ejecute webpackel comando, 加载se mostrará la configuración interna)
  • Todas las herramientas de compilación están basadas en plataformas y adoptan nodejsla modularidad .默认commonjs
  1. La configuración es la siguiente
const {
    
     resolve } = require("path"); // node 内置核心模块,用来处理路径问题。
module.exports = {
    
    
  entry: "./src/index.js", // 入口文件
  output: {
    
    
    // 输出配置
    filename: "built.js", // 输出文件名
    path: resolve(__dirname, "build"), // 输出文件路径配置
  },
  mode: "development", //开发环境
};
  1. Ejecutar comando:webpack

3.2 Recursos de estilo de empaquetado

  1. crear un archivo
/* index.css */
html, body{
    
    
  margin: 0;
  padding: 0;
  height: 100%;
  background-color: pink;
}
// index.js
// 引入样式资源
import './index.css';
import './index.less';
// index.less
#title {
  color: #fff;
}
  1. Descargue e instale el paquete del cargador
npm i css-loader style-loader less-loader less -D
  1. Modificar el archivo de configuración
// resolve用来拼接绝对路径的方法
const {
    
     resolve } = require("path");

module.exports = {
    
    
  // webpack配置
  // 入口起点
  entry: "./src/index.js",
  // 输出
  output: {
    
    
    // 输出文件名
    filename: "built.js",
    // 输出路径
    // __dirname nodejs的变量,代表当前文件的目录绝对路径
    path: resolve(__dirname, "build"),
  },
  // loader的配置
  module: {
    
    
    rules: [
      // 详细loader配置
      // 不同文件必须配置不同loader处理
      {
    
    
        // 匹配哪些文件
        test: /\.css$/,
        // 使用哪些loader进行处理
        use: [
          // use数组中loader执行顺序:从右到左,从下到上 依次执行
          // 创建style标签,将js中的样式资源插入进行,添加到head中生效
          "style-loader",
          // 将css文件变成commonjs模块加载js中,里面内容是样式字符串
          "css-loader",
        ],
      },
      {
    
    
        test: /\.less$/,
        use: [
          "style-loader",
          "css-loader",
          // 将less文件编译成css文件
          // 需要下载 less-loader和less
          "less-loader",
        ],
      },
    ],
  },
  // plugins的配置
  plugins: [
    // 详细plugins的配置
  ],
  // 模式
  mode: "development", // 开发模式
  // mode: 'production'
};

  1. Ejecutar comando: paquete web

3.3 Empaquetado de recursos HTML

  1. crear un archivo
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>webpack</title>
</head>

<body>
  <h1 id="title">hello html</h1>
</body>

</html>
function add(x, y) {
    
    
  return x + y;
}

console.log(add(2, 3));
  1. Descargue e instale el paquete de complementos
npm install --save-dev html-webpack-plugin
  1. Modificar el archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/index.js",
  output: {
    
    
    filename: "built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      // loader的配置
    ],
  },
  plugins: [
    // plugins的配置
    // html-webpack-plugin
    // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
    // 需求:需要有结构的HTML文件
    new HtmlWebpackPlugin({
    
    
      // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
      template: "./src/index.html",
    }),
  ],
  mode: "development",
};

3.4 Paquete de recursos de imágenes

  1. crear un archivo
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>webpack</title>
</head>
<body>
  <div id="box1"></div>
  <div id="box2"></div>
  <div id="box3"></div>
  <img src="./angular.jpg" alt="angular">
</body>
</html>
import './index.less';
#box1{
  width: 100px;
  height: 100px;
  background-image: url('./vue.jpg');
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

#box2{
  width: 200px;
  height: 200px;
  background-image: url('./react.png');
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

#box3{
  width: 300px;
  height: 300px;
  background-image: url('./angular.jpg');
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
  1. Descargue e instale el paquete del cargador
npm install --save-dev html-loader url-loader file-loader
  1. Modificar el archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/index.js",
  output: {
    
    
    filename: "built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.less$/,
        // 要使用多个loader处理用use
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
    
    
        // 问题:默认处理不了html中img图片
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        // 使用一个loader
        // 下载 url-loader file-loader,url-loader 依赖 file-loader
        loader: "url-loader",
        options: {
    
    
          // 图片大小小于8kb,就会被base64处理
          // 优点: 减少请求数量(减轻服务器压力)
          // 缺点:图片体积会更大(文件请求速度更慢)
          limit: 8 * 1024,
          // 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
          // 解析时会出问题:[object Module]
          // 解决:关闭url-loader的es6模块化,使用commonjs解析
          esModule: false,
          // 给图片进行重命名
          // [hash:10]取图片的hash的前10位
          // [ext]取文件原来扩展名
          name: "[hash:10].[ext]",
        },
      },
      {
    
    
        test: /\.html$/,
        // 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
        loader: "html-loader",
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
    }),
  ],
  mode: "development",
};

3.5 Empaquetado de otros recursos

  1. alcance de uso

No es necesario realizar ningún procesamiento, solo la salida intacta, como los iconos de fuente.

  1. archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/index.js",
  output: {
    
    
    filename: "built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
    
    
        // 排除css/js/html资源
        exclude: /\.(css|js|html|less)$/,
        loader: "file-loader",
        options: {
    
    
          name: "[hash:10].[ext]",
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
    }),
  ],
  mode: "development",
};

3.6 servidor de desarrollo

  1. efecto

Servidor de desarrollo devServer: utilizado para la automatización (compilar automáticamente, abrir automáticamente el navegador, actualizar automáticamente el navegador), los desarrolladores solo necesitan concentrarse en la codificación

  1. archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/index.js",
  output: {
    
    
    filename: "built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
    
    
        // 排除css/js/html资源
        exclude: /\.(css|js|html|less)$/,
        loader: "file-loader",
        options: {
    
    
          name: "[hash:10].[ext]",
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
    }),
  ],
  mode: "development",

  // 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
  // 特点:只会在内存中编译打包,不会有任何输出
  // 启动devServer指令为:npx webpack-dev-server
  devServer: {
    
    
    // 项目构建后路径
    contentBase: resolve(__dirname, "build"),
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    // 自动打开浏览器(默认浏览器)
    open: true,
  },
};

  • npx es una herramienta para ejecutar paquetes de Node. Se incluye con npm desde la versión 5.2.
  • Por defecto, primero verifique si el paquete a ejecutar existe en la ruta (es decir, en el proyecto); si existe, se ejecutará; si no existe, significa que el paquete no se ha instalado, se instalará npx su última versión, y luego ejecútela;
  1. ejecutar comando
npx webpack-dev-server

3.7 Configuración del entorno de desarrollo

  1. Objetivo

Configuración del entorno de desarrollo: permita que se ejecute el código (simplemente ejecute el código)

Ejecute el comando del proyecto:

  • webpack: generará el resultado del empaquetado
  • npx webpack-dev-server: solo en 内存中编译打包,没有输出
  1. archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      // loader的配置
      {
    
    
        // 处理less资源
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
    
    
        // 处理css资源
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
    
    
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        loader: "url-loader",
        options: {
    
    
          limit: 8 * 1024,
          name: "[hash:10].[ext]",
          // 关闭es6模块化
          esModule: false,
          outputPath: "imgs",
        },
      },
      {
    
    
        // 处理html中img资源
        test: /\.html$/,
        loader: "html-loader",
      },
      {
    
    
        // 处理其他资源
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: "file-loader",
        options: {
    
    
          name: "[hash:10].[ext]",
          outputPath: "media",
        },
      },
    ],
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
    }),
  ],
  mode: "development",
  devServer: {
    
    
    contentBase: resolve(__dirname, "build"),
    compress: true,
    port: 3000,
    open: true,
  },
};

  1. ejecutar comando
npx webpack-dev-server

4. Configuración básica del entorno de producción de paquetes web.

Por qué configurar el entorno de producción por separado

  • En el entorno de desarrollo, css se coloca en js, lo que da como resultado archivos js más grandes
  • Debido a que el css se coloca en el js, el css no tendrá efecto hasta que se cargue el js, lo que hará que parpadee
  • El propósito del entorno de desarrollo es hacer que el código se ejecute y se depure; el propósito del entorno de producción es hacer que el código se ejecute más rápido y sin problemas. El entorno de producción utilizará compresión de código, garantía de compatibilidad css y otros medios.
  • La compresión, la compatibilidad, etc. toman mucho tiempo, y ponerlo en el entorno de desarrollo hará que la compilación sea más lenta, lo que no es propicio para el desarrollo y la depuración.

4.1 Extraiga css en un archivo separado

  1. descargar complemento
npm install --save-dev mini-css-extract-plugin
  1. Modificar el archivo de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: [
          // 创建style标签,将样式放入
          // 'style-loader', 

          // 这个loader取代style-loader。作用:提取js中的css成单独文件
          MiniCssExtractPlugin.loader,
          // 将css文件整合到js文件中
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
    
    
      // 对输出的css文件进行重命名,默认名称是main.css
      filename: 'css/built.css'
    })
  ],
  mode: 'development'
};
  • style-loader: Cree una etiqueta de estilo y coloque el estilo en
  • MiniCssExtractPlugin.loader: extraiga el css en js en un archivo separado

Procesamiento de compatibilidad 4.2 css

  1. descargar cargador
npm install --save-dev postcss-loader postcss-preset-env
  1. Modificar el archivo de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 设置nodejs环境变量
// process.env.NODE_ENV = 'development';

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          /*
            css兼容性处理:postcss --> postcss-loader postcss-preset-env

            帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式

            "browserslist": {
              // 开发环境 --> 设置node环境变量:process.env.NODE_ENV = development
              "development": [
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version"
              ],
              // 生产环境:默认是看生产环境
              "production": [
                ">0.2%",
                "not dead",
                "not op_mini all"
              ]
            }
          */
          // 使用loader的默认配置
          // 'postcss-loader',
          // 修改loader的配置
          {
    
    
            loader: 'postcss-loader',
            options: {
    
    
              ident: 'postcss',
              plugins: () => [
                // postcss的插件
                require('postcss-preset-env')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
    
    
      filename: 'css/built.css'
    })
  ],
  mode: 'development'
};

  1. Modificar paquete.json
{
    
    
  "browserslist": {
    
    
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  }
}

4.3 comprimir css

  1. Descargar el paquete de instalación
npm install --save-dev optimize-css-assets-webpack-plugin
  1. Modificar el archivo de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

// 设置nodejs环境变量
// process.env.NODE_ENV = 'development';

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
    
    
            loader: 'postcss-loader',
            options: {
    
    
              ident: 'postcss',
              plugins: () => [
                // postcss的插件
                require('postcss-preset-env')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
    
    
      filename: 'css/built.css'
    }),
    // 压缩css
    new OptimizeCssAssetsWebpackPlugin()
  ],
  // optimization: {
    
    
  //   minimize: true,
  //   minimizer: [
  //     // 压缩 js
  //     new TerserWebpackPlugin(),
  //     // 压缩css 
  //     new OptimizeCssAssetsWebpackPlugin(),
  //   ],
  // },
  mode: 'development'
};
  • Cuando se presenta la documentación oficial del paquete web, OptimizeCssAssetsWebpackPluginlos complementos no están configurados en pluginsuna matriz. En su lugar, configúrelos en optimization.minimizerla matriz.
  • El motivo es: configurado en plugins, el paquete web utilizará este complemento al inicio. Y configurado en optimization.minimizer, solo se utilizará optimization.minimizecuando esta característica esté habilitada. Por lo tanto, webpack recomienda que los complementos como la compresión se configuren en optimization.minimizeruna matriz. para facilitar optimization.minimizeel control unificado. (El entorno de producción habilitará minimizar por defecto)
  • Cabe señalar que si está configurado minimizer, significa que el desarrollador está 自定义comprimiendo el complemento. El compresor JS interno se sobrescribirá. Por lo tanto, la compresión js debe configurarse manualmente.

Verificación de sintaxis 4.4 js

  1. Descargar el paquete de instalación
npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
  1. Modificar el archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      /*
        语法检查: eslint-loader 依赖 eslint 库
          注意:只检查自己写的源代码,第三方的库是不用检查的
          设置检查规则:
            package.json中eslintConfig中设置~
              "eslintConfig": {
                // 继承 airbnb-base 的规则检查
                "extends": "airbnb-base"
              }
            airbnb(检查规则) --> eslint-config-airbnb-base  eslint-plugin-import eslint
      */
      {
    
    
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
    
    
          // 自动修复eslint的错误
          fix: true,
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
    }),
  ],
  mode: "development",
};

  1. Configurar paquete.json

Configurar reglas de inspección

{
    
    
  "eslintConfig": {
    
    
    "extends": "airbnb-base",
    "env": {
    
    
      // eslint不认识 window、navigator全局变量,支持浏览器端全局变量
      "browser": true
    }
  }
}

Procesamiento de compatibilidad 4.5 js y conversión de sintaxis es6

  1. efecto

Convierta la gramática de es6 a la gramática de es5

  1. Descargar el paquete de instalación
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/polyfill core-js
  1. Modificar el archivo de configuración
const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      /*
        js兼容性处理:babel-loader @babel/core (babel的核心库)
          1. 基本js兼容性处理 --> @babel/preset-env
            问题:只能转换基本语法,如promise高级语法不能转换
          2. 全部js兼容性处理 --> @babel/polyfill  
            问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
            使用方法:
              引入即可,在index.js中 import '@babel/polyfill ';
          3. 需要做兼容性处理的就做:按需加载  --> core-js
      */
      {
    
    
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: {
    
    
          // 预设:指示babel做怎么样的兼容性处理
          presets: [
            [
              "@babel/preset-env",
              {
    
    
                // 按需加载
                useBuiltIns: "usage",
                // 指定core-js版本
                corejs: {
    
    
                  version: 3,
                },
                // 指定兼容性做到哪个版本浏览器
                targets: {
    
    
                  chrome: "60",
                  firefox: "60",
                  ie: "9",
                  safari: "10",
                  edge: "17",
                },
              },
            ],
          ],
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
    }),
  ],
  mode: "development",
};

compresión 4.6js

  1. El código js se comprimirá automáticamente en el entorno de producción.
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    })
  ],
  // 生产环境下会自动压缩js代码
  mode: 'production'
};

En el entorno de producción, el complemento UglifyJsPlugin estará habilitado para comprimir js.

  1. La configuración manual
    del paquete web cree que si el minimizador está configurado, significa que el desarrollador está personalizando para comprimir el complemento. El compresor JS interno se sobrescribirá.

La configuración debe modificarse de la siguiente manera:

const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserWebpackPlugin = require("terser-webpack-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.js",
    path: resolve(__dirname, "build"),
  },
  optimization: {
    
    
    minimize: true,
    minimizer: [
      // 压缩 js
      new TerserWebpackPlugin(),
      // 压缩css
      new OptimizeCssAssetsWebpackPlugin(),
    ],
  },
  mode: "development",
};

4.7 Compresión HTML

  1. Modificar el archivo de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html',
      // 压缩html代码
      minify: {
    
    
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    })
  ],
  mode: 'production'
};

4.8 Configuración del entorno de producción

  1. Modificar el archivo de configuración
const {
    
     resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    
    
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
    
    
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: [...commonCssLoader]
      },
      {
    
    
        test: /\.less$/,
        use: [...commonCssLoader, 'less-loader']
      },
      /*
        正常来讲,一个文件只能被一个loader处理。
        当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
          先执行eslint 再执行babel
      */
      {
    
    
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
    
    
          fix: true
        }
      },
      {
    
    
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
    
    
          presets: [
            [
              '@babel/preset-env',
              {
    
    
                useBuiltIns: 'usage',
                corejs: {
    
    version: 3},
                targets: {
    
    
                  chrome: '60',
                  firefox: '50'
                }
              }
            ]
          ]
        }
      },
      {
    
    
        test: /\.(jpg|png|gif)/,
        loader: 'url-loader',
        options: {
    
    
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          outputPath: 'imgs',
          esModule: false
        }
      },
      {
    
    
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
    
    
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
    
    
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: 'css/built.css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html',
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  mode: 'production'
};

Cinco, configuración de optimización del paquete web

5.1 Descripción general de la optimización del rendimiento

  1. Clasificación de optimización del rendimiento
  • Optimización del rendimiento del entorno de desarrollo
  • Optimización del rendimiento del entorno de producción
  1. Optimización del rendimiento del entorno de desarrollo
  • Optimizar la velocidad de creación de paquetes
    • HMR
  • Optimizar la depuración de código
    • mapa fuente
  1. Optimización del rendimiento del entorno de producción
  • Optimizar la velocidad de creación de paquetes
    • uno de
    • babel-caché
    • Envasado multiproceso
    • exterioridad
    • dll
  • Optimizar el rendimiento del código
    • Caché (hash-chunkhash-contenthash)
    • árbol temblando
    • división de código
    • carga diferida/precarga
    • pwa

5.2 HMR

  1. introducir
  • HMR: hot module replacementReemplazo de módulo caliente / Reemplazo de módulo caliente
  • Función: si un módulo cambia, volverá a empaquetar este 一个módulo (y 不是打包所有模块) mejorará en gran medida la velocidad de construcción
  • Archivo de estilo: puede usar la función HMR: porque style-loaderse implementa internamente
  • Archivo js: 不能use la función HMR de forma predeterminada: 修改se requiere el código js, ​​agregue el código que admite la función HMR
    • 非入口js文件Nota: la función HMR solo puede procesar otros archivos para el procesamiento js .
  • archivo html: 不能la función HMR se usa de forma predeterminada y causará problemas: el archivo html no se puede actualizar en caliente (el código html escrito localmente no actualiza el navegador) (la función HMR no es necesaria)
    • Solución: modifique la entrada de entrada e importe el archivo htmlentry: ['./src/js/index.js', './src/index.html']
  1. js para habilitar la función HMR
// index.js
// 引入
import print from './print';
import '../css/iconfont.css';
import '../css/index.less';

console.log('index.js文件被加载了~');

print();

function add(x, y) {
    
    
  return x + y;
}

console.log(add(1, 3));

if (module.hot) {
    
    
  // 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
  module.hot.accept('./print.js', function() {
    
    
    // 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
    print();
  });
}
// print.js
console.log('print.js被加载了~');

function print() {
    
    
  const content = 'hello print';
  console.log(content);
}

export default print;
  1. archivo de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: ['./src/js/index.js', './src/index.html'],
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      // loader的配置
      {
    
    
        // 处理less资源
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
    
    
        // 处理css资源
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
    
    
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
    
    
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          // 关闭es6模块化
          esModule: false,
          outputPath: 'imgs'
        }
      },
      {
    
    
        // 处理html中img资源
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
    
    
        // 处理其他资源
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
    
    
          name: '[hash:10].[ext]',
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    })
  ],
  mode: 'development',
  devServer: {
    
    
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    // 开启HMR功能
    // 当修改了webpack配置,新配置要想生效,必须重新webpack服务
    hot: true
  }
};

5.3 mapa fuente

  1. Introducción

source-map: una forma de proporcionar código fuente al código posterior a la compilación 映射技术(si hay un error en el código posterior a la compilación, 映射puede ser 追踪源代码incorrecto al pasar)

  1. categoría

[en línea-|oculto-|eval-][nosources-][barato-[módulo-]]source-map

  • mapa fuente: externo
    • Información exacta sobre el código de error y la ubicación del error en el código fuente
  • en línea-fuente-mapa: en línea
    • Genere solo un mapa fuente en línea
    • Información exacta sobre el código de error y la ubicación del error en el código fuente
  • mapa-de-fuente-oculto: externo
    • código de error motivo del error, pero no ubicación del error
    • No se pueden rastrear los errores del código fuente, solo se solicita la ubicación incorrecta del código después de la construcción.
    • Puede ocultar el código fuente, no el código de compilación
  • eval-fuente-mapa: en línea
    • Cada archivo genera un mapa fuente correspondiente, todo en evaluación
    • Información exacta sobre el código de error y la ubicación del error en el código fuente
  • nosources-source-mapa: externo
    • Información precisa del código de error, pero sin información del código fuente
    • Puede ocultar el código fuente, también ocultar el código de compilación
  • mapa-fuente-barato: externo
    • Información exacta sobre el código de error y la ubicación del error en el código fuente
    • sólo exacto a la línea
  • mapa fuente-módulo-barato: externo
    • Información exacta sobre el código de error y la ubicación del error en el código fuente
    • El módulo agregará el mapa fuente del cargador.
  1. La diferencia entre en línea y externo
  • El archivo se genera externamente, pero no en línea (en línea coloca directamente la información del mapa de origen en js)
  • Las compilaciones en línea son más rápidas
  1. selección de mapa fuente
  • Entorno de desarrollo: velocidad rápida y depuración más amigable
    • 速度快(eval>inline>barato>…) eval-cheap-souce-map > eval-source-map
    • La depuración es más amigable: source-map > cheap-module-souce-map > cheap-souce-map
    • Sugerencias: eval-source-map (vue, react scaffolding) / eval-cheap-module-souce-map
  • Entorno de producción: ¿debería ocultarse el código fuente?, ¿debería ser más amigable la depuración?
    • La inserción aumentará el tamaño del código, así que no lo haga en el entorno de producción.
    • nosources-source-map ocultar todo
    • hidden-source-map solo oculta el código fuente y mostrará el mensaje de error del código después de la compilación
    • source-map (depuración amigable) / cheap-module-source-map (más rápido)
  1. información de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: ['./src/js/index.js', './src/index.html'],
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      // loader的配置
      {
    
    
        // 处理less资源
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
    
    
        // 处理css资源
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
    
    
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
    
    
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          // 关闭es6模块化
          esModule: false,
          outputPath: 'imgs'
        }
      },
      {
    
    
        // 处理html中img资源
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
    
    
        // 处理其他资源
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
    
    
          name: '[hash:10].[ext]',
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    })
  ],
  mode: 'development',
  devServer: {
    
    
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true
  },
  devtool: 'eval-source-map'
};

5.4 uno de

  1. Resolver el problema
  • Sin usar oneOf, todas las reglas coincidirán una vez, algunas se pueden alcanzar y otras no.
  • Al usar oneOf, el cargador en oneOf solo coincidirá con uno
  • Optimice el embalaje y la velocidad de construcción del entorno de producción
  1. archivo de configuración
const {
    
     resolve } = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = "production";

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  "css-loader",
  {
    
    
    // 还需要在package.json中定义browserslist
    loader: "postcss-loader",
    options: {
    
    
      ident: "postcss",
      plugins: () => [require("postcss-preset-env")()],
    },
  },
];

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: "pre",
        loader: "eslint-loader",
        options: {
    
    
          fix: true,
        },
      },
      {
    
    
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
    
    
            test: /\.css$/,
            use: [...commonCssLoader],
          },
          {
    
    
            test: /\.less$/,
            use: [...commonCssLoader, "less-loader"],
          },
          {
    
    
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader",
            options: {
    
    
              presets: [
                [
                  "@babel/preset-env",
                  {
    
    
                    useBuiltIns: "usage",
                    corejs: {
    
     version: 3 },
                    targets: {
    
    
                      chrome: "60",
                      firefox: "50",
                    },
                  },
                ],
              ],
            },
          },
          {
    
    
            test: /\.(jpg|png|gif)/,
            loader: "url-loader",
            options: {
    
    
              limit: 8 * 1024,
              name: "[hash:10].[ext]",
              outputPath: "imgs",
              esModule: false,
            },
          },
          {
    
    
            test: /\.html$/,
            loader: "html-loader",
          },
          {
    
    
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: "file-loader",
            options: {
    
    
              outputPath: "media",
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: "css/built.css",
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
  ],
  mode: "production",
};

5.5 Almacenamiento en caché

  1. clasificación de caché
  • Caché de Babel (hacer que el segundo paquete se construya más rápido)
    • directorio de caché: verdadero
  • Caché de recursos de archivo (deje que el código se ejecute en línea y ejecute mejor el caché)
    • Escenario de uso: el servidor está configurado con caché y los usuarios usarán el archivo de caché. En este momento, se lanza una versión de corrección de errores y se reemplazará el archivo modificado. Cómo hacer que el usuario abandone el caché y use un nuevo archivo
    • Método de caché de recursos de archivo
      • hash: se genera un valor hash único cada vez que se construye wepack.
        • Problema: porque js y css usan un valor hash al mismo tiempo. Si se vuelve a empaquetar, todos los cachés se invalidarán. (Tal vez solo cambié un archivo)
      • chunkhash: el valor hash generado de acuerdo con el fragmento. Si el empaque proviene del mismo trozo, el valor hash será el mismo
        • Problema: los valores hash de js y css siguen siendo los mismos porque css se introdujo en js, por lo que pertenecen al mismo fragmento
      • contenthash: genera un valor hash basado en el contenido del archivo. Los valores hash de diferentes archivos deben ser diferentes
  1. archivo de configuración
const {
    
     resolve } = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = "production";

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  "css-loader",
  {
    
    
    // 还需要在package.json中定义browserslist
    loader: "postcss-loader",
    options: {
    
    
      ident: "postcss",
      plugins: () => [require("postcss-preset-env")()],
    },
  },
];

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.[contenthash:10].js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: "pre",
        loader: "eslint-loader",
        options: {
    
    
          fix: true,
        },
      },
      {
    
    
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
    
    
            test: /\.css$/,
            use: [...commonCssLoader],
          },
          {
    
    
            test: /\.less$/,
            use: [...commonCssLoader, "less-loader"],
          },
          /*
            正常来讲,一个文件只能被一个loader处理。
            当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
              先执行eslint 在执行babel
          */
          {
    
    
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader",
            options: {
    
    
              presets: [
                [
                  "@babel/preset-env",
                  {
    
    
                    useBuiltIns: "usage",
                    corejs: {
    
     version: 3 },
                    targets: {
    
    
                      chrome: "60",
                      firefox: "50",
                    },
                  },
                ],
              ],
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true,
            },
          },
          {
    
    
            test: /\.(jpg|png|gif)/,
            loader: "url-loader",
            options: {
    
    
              limit: 8 * 1024,
              name: "[hash:10].[ext]",
              outputPath: "imgs",
              esModule: false,
            },
          },
          {
    
    
            test: /\.html$/,
            loader: "html-loader",
          },
          {
    
    
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: "file-loader",
            options: {
    
    
              outputPath: "media",
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: "css/built.[contenthash:10].css",
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
  ],
  mode: "production",
  devtool: "source-map",
};

5.6 sacudidas de árboles y sacudidas de árboles

  1. Objetivo

sacudir el árbol: elimine el código inútil y reduzca el tamaño del código

  1. premisa
  • Debe usar la modularidad ES6
  • Abra el entorno de producción.
  1. pregunta

Puede cssmatar @babel/polyfillarchivos (efecto secundario)

Configurar en paquete.json:

  • "sideEffects": falso Todos los códigos no tienen efectos secundarios (todos pueden sacudir árboles)
  • "sideEffects": [" .css", " .less"] No realizar agitación de árboles
  1. archivo de configuración
const {
    
     resolve } = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = "production";

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  "css-loader",
  {
    
    
    // 还需要在package.json中定义browserslist
    loader: "postcss-loader",
    options: {
    
    
      ident: "postcss",
      plugins: () => [require("postcss-preset-env")()],
    },
  },
];

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.[contenthash:10].js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: "pre",
        loader: "eslint-loader",
        options: {
    
    
          fix: true,
        },
      },
      {
    
    
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
    
    
            test: /\.css$/,
            use: [...commonCssLoader],
          },
          {
    
    
            test: /\.less$/,
            use: [...commonCssLoader, "less-loader"],
          },
          {
    
    
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader",
            options: {
    
    
              presets: [
                [
                  "@babel/preset-env",
                  {
    
    
                    useBuiltIns: "usage",
                    corejs: {
    
     version: 3 },
                    targets: {
    
    
                      chrome: "60",
                      firefox: "50",
                    },
                  },
                ],
              ],
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true,
            },
          },
          {
    
    
            test: /\.(jpg|png|gif)/,
            loader: "url-loader",
            options: {
    
    
              limit: 8 * 1024,
              name: "[hash:10].[ext]",
              outputPath: "imgs",
              esModule: false,
            },
          },
          {
    
    
            test: /\.html$/,
            loader: "html-loader",
          },
          {
    
    
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: "file-loader",
            options: {
    
    
              outputPath: "media",
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: "css/built.[contenthash:10].css",
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
  ],
  mode: "production",
  devtool: "source-map",
};

división de código 5.7

  1. Objetivo
  • Segmentación de código, divida un código grande en múltiples códigos, cárguelos en paralelo y mejore la velocidad de carga
  • Implementar carga bajo demanda
  1. Método 1: entrada múltiple

Dividir archivos por múltiples entradas

const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  // 单页面应用 单入口最终输出一个bundle
  // entry: './src/js/index.js',
  entry: {
    
    
    // 多页面应用 多入口:每个入口输出一个bundle
    index: "./src/js/index.js",
    test: "./src/js/test.js",
  },
  output: {
    
    
    // [name]:取文件名
    filename: "js/[name].[contenthash:10].js",
    path: resolve(__dirname, "build"),
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
  ],
  mode: "production",
};

  1. Método 2: fragmentos divididos
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  // 单入口
  // entry: './src/js/index.js',
  entry: {
    
    
    index: './src/js/index.js',
    test: './src/js/test.js'
  },
  output: {
    
    
    // [name]:取文件名
    filename: 'js/[name].[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html',
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  /*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件(如果公共文件太小,也不会单独生成chunk)。如果有会打包成单独一个chunk
  */
  optimization: {
    
    
    splitChunks: {
    
    
      chunks: 'all'
    }
  },
  mode: 'production'
};
  1. Método 3: a través del código js, ​​deje que un archivo se empaquete en un fragmento por separado
  • importSintaxis de importación dinámica: un archivo se puede empaquetar por separado
  • webpackChunkName: Configure el nombre del archivo empaquetado, si no está configurado, es 0, 1, 2, 3...
function sum(...args) {
    
    
  return args.reduce((p, c) => p + c, 0);
}

import(/* webpackChunkName: 'test' */ "./test")
  .then(({
     
      mul, count }) => {
    
    
    // 文件加载成功~
    // eslint-disable-next-line
    console.log(mul(2, 5));
  })
  .catch(() => {
    
    
    // eslint-disable-next-line
    console.log("文件加载失败~");
  });

// eslint-disable-next-line
console.log(sum(1, 2, 3, 4));

5.8 carga diferida y carga diferida

console.log('index.js文件被加载了~');

// import { mul } from './test';

document.getElementById('btn').onclick = function() {
    
    
  // 懒加载~:当文件需要使用时才加载~
  // 预加载 prefetch:会在使用之前,提前加载js文件 
  // 正常加载可以认为是并行加载(同一时间加载多个文件)  
  // 预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源
  import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then(({
     
      mul }) => {
    
    
    console.log(mul(4, 5));
  });
};

La carga previa debe usarse con precaución, porque los problemas de compatibilidad son relativamente grandes.

5.9 pwa y aplicación de desarrollo web progresiva (accesible sin conexión)

  1. status quo

Debido a problemas de compatibilidad, no se usa mucho y algunos de los principales fabricantes lo están usando (Taobao)

  1. Descargar el paquete de instalación

Use workbox (complemento de código abierto de Google), el paquete web necesita instalar el complemento de caja de trabajo-webpack

npm install --save-dev workbox-webpack-plugin
  1. archivo de configuración
const {
    
     resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    
    
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
    
    
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
    
    
          fix: true
        }
      },
      {
    
    
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
    
    
            test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
    
    
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          {
    
    
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
    
    
              presets: [
                [
                  '@babel/preset-env',
                  {
    
    
                    useBuiltIns: 'usage',
                    corejs: {
    
     version: 3 },
                    targets: {
    
    
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ],
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true
            }
          },
          {
    
    
            test: /\.(jpg|png|gif)/,
            loader: 'url-loader',
            options: {
    
    
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              outputPath: 'imgs',
              esModule: false
            }
          },
          {
    
    
            test: /\.html$/,
            loader: 'html-loader'
          },
          {
    
    
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: 'file-loader',
            options: {
    
    
              outputPath: 'media'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: 'css/built.[contenthash:10].css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html',
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true
      }
    }),
    new WorkboxWebpackPlugin.GenerateSW({
    
    
      /*
        1. 帮助serviceworker快速启动
        2. 删除旧的 serviceworker

        生成一个 serviceworker 配置文件(service-worker.js)~
      */
      clientsClaim: true,
      skipWaiting: true
    })
  ],
  mode: 'production',
  devtool: 'source-map'
};
import {
    
     mul } from "./test";
import "../css/index.css";

function sum(...args) {
    
    
  return args.reduce((p, c) => p + c, 0);
}

// eslint-disable-next-line
console.log(mul(2, 3));
// eslint-disable-next-line
console.log(sum(1, 2, 3, 4));

/*
  1. eslint不认识 window、navigator全局变量
    解决:需要修改package.json中eslintConfig配置
      "env": {
        "browser": true // 支持浏览器端全局变量
      }
   2. sw代码必须运行在服务器上
      方式一:直接使用 nodejs
      方式二:使用 serve 包
        npm i serve -g
        serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
*/
// 注册serviceWorker
// 处理兼容性问题
if ("serviceWorker" in navigator) {
    
    
  window.addEventListener("load", () => {
    
    
    navigator.serviceWorker
      .register("/service-worker.js")
      .then(() => {
    
    
        console.log("sw注册成功了~");
      })
      .catch(() => {
    
    
        console.log("sw注册失败了~");
      });
  });
}

5.10 Envasado multiproceso

  1. Descargar el paquete de instalación
npm install --save-dev thread-loade
  1. archivo de configuración
const {
    
     resolve } = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const WorkboxWebpackPlugin = require("workbox-webpack-plugin");

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = "production";

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  "css-loader",
  {
    
    
    // 还需要在package.json中定义browserslist
    loader: "postcss-loader",
    options: {
    
    
      ident: "postcss",
      plugins: () => [require("postcss-preset-env")()],
    },
  },
];

module.exports = {
    
    
  entry: "./src/js/index.js",
  output: {
    
    
    filename: "js/built.[contenthash:10].js",
    path: resolve(__dirname, "build"),
  },
  module: {
    
    
    rules: [
      {
    
    
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: "pre",
        loader: "eslint-loader",
        options: {
    
    
          fix: true,
        },
      },
      {
    
    
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
    
    
            test: /\.css$/,
            use: [...commonCssLoader],
          },
          {
    
    
            test: /\.less$/,
            use: [...commonCssLoader, "less-loader"],
          },
          {
    
    
            test: /\.js$/,
            exclude: /node_modules/,
            use: [
              /* 
                放在某一个loader的后面,会对该loader开启多进程打包。 
                进程启动大概为600ms,进程通信也有开销。
                只有工作消耗时间比较长,才需要多进程打包
              */
              {
    
    
                loader: "thread-loader",
                options: {
    
    
                  workers: 2, // 进程2个
                },
              },
              {
    
    
                loader: "babel-loader",
                options: {
    
    
                  presets: [
                    [
                      "@babel/preset-env",
                      {
    
    
                        useBuiltIns: "usage",
                        corejs: {
    
     version: 3 },
                        targets: {
    
    
                          chrome: "60",
                          firefox: "50",
                        },
                      },
                    ],
                  ],
                  // 开启babel缓存
                  // 第二次构建时,会读取之前的缓存
                  cacheDirectory: true,
                },
              },
            ],
          },
          {
    
    
            test: /\.(jpg|png|gif)/,
            loader: "url-loader",
            options: {
    
    
              limit: 8 * 1024,
              name: "[hash:10].[ext]",
              outputPath: "imgs",
              esModule: false,
            },
          },
          {
    
    
            test: /\.html$/,
            loader: "html-loader",
          },
          {
    
    
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: "file-loader",
            options: {
    
    
              outputPath: "media",
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: "css/built.[contenthash:10].css",
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
    
    
      template: "./src/index.html",
      minify: {
    
    
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
    new WorkboxWebpackPlugin.GenerateSW({
    
    
      /*
        1. 帮助serviceworker快速启动
        2. 删除旧的 serviceworker

        生成一个 serviceworker 配置文件~
      */
      clientsClaim: true,
      skipWaiting: true,
    }),
  ],
  mode: "production",
  devtool: "source-map",
};

5.11 externos

  1. efecto

Evite que ciertos paquetes se exporten a ciertas dependencias, como jq, queremos obtenerlo desde el enlace CDN y no queremos empaquetarlo.

  1. archivo de configuración
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    })
  ],
  mode: 'production',
  externals: {
    
    
    // 拒绝jQuery被打包进来
    jquery: 'jQuery'
  }
};
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>webpack</title>
</head>

<body>
  <h1 id="title">hello html</h1>
  <!-- 需要手动引入进来 -->
  <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
</body>

</html>

5.12 dll y biblioteca de enlaces dinámicos

  1. Objetivo

Utilice la tecnología dll para empaquetar algunas bibliotecas (bibliotecas de terceros: jquery, react, vue...) por separado, esta operación es previa a la operación. Cuando el negocio real está empaquetado, no hay necesidad de empaquetar dichos archivos, solo necesita empaquetar el código comercial e importar la biblioteca de terceros preempaquetada.

  1. archivo de configuración
// webpack.dll.js
/*
  使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包
    当你运行 webpack 时,默认查找 webpack.config.js 配置文件
    需求:需要运行 webpack.dll.js 文件
      --> webpack --config webpack.dll.js
*/

const {
    
     resolve } = require('path');
const webpack = require('webpack');

module.exports = {
    
    
  entry: {
    
    
    // 最终打包生成的[name] --> jquery
    // ['jquery'] --> 要打包的库是jquery
    jquery: ['jquery'],
  },
  output: {
    
    
    filename: '[name].js',
    path: resolve(__dirname, 'dll'),
    library: '[name]_[hash]' // 打包的库里面向外暴露出去的内容叫什么名字
  },
  plugins: [
    // 打包生成一个 manifest.json --> 提供和jquery映射
    new webpack.DllPlugin({
    
    
      name: '[name]_[hash]', // 映射库的暴露的内容名称
      path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
    })
  ],
  mode: 'production'
};

// webpack.config.js
const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
    
    
  entry: './src/index.js',
  output: {
    
    
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './src/index.html'
    }),
    // 告诉webpack哪些库不参与打包,同时使用时的名称也得变~
    new webpack.DllReferencePlugin({
    
    
      manifest: resolve(__dirname, 'dll/manifest.json')
    }),
    // 将某个文件打包输出去,并在html中自动引入该资源
    new AddAssetHtmlWebpackPlugin({
    
    
      filepath: resolve(__dirname, 'dll/jquery.js')
    })
  ],
  mode: 'production'
};

Seis, detalles de configuración del paquete web

6.1 entrada

punto de entrada

  1. cadena
entry: './src/index.js'
  • sola entrada
  • forma empaquetada一个chunk
  • 一个bundlearchivo de salida
  • El nombre predeterminado en este momento chunkesmain
  1. formación
entry: ['./src/index.js', './src/add.js']
  • multi entrada
  • Eventualmente, todos los archivos de entrada solo se formarán 一个chunky solo se generarán archivos 一个bundle.
  • El nombre predeterminado en este momento chunkesmain
  • Solo haga que la actualización en caliente de html tenga efecto en la función HMR
  • Los archivos de matriz generalmente no son interdependientes, pero están empaquetados juntos por alguna razón
  1. objeto
  entry: {
    
    
    index: "./src/index.js",
    add: "./src/add.js"
  }
  • multi entrada
  • Si hay varios archivos de entrada, se formarán varios chunky se generarán varios bundlearchivos .
  • El nombre en este momento chunkeskey
  1. uso especial
entry: {
    
    
    // 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
    index: ["./src/index.js", "./src/count.js"],
    // 形成一个chunk,输出一个bundle文件。
    add: "./src/add.js"
  }

6.2 salida

const {
    
     resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    
    
  entry: "./src/index.js",
  output: {
    
    
    // 文件名称(指定名称+目录)
    filename: "js/[name].js",
    // 输出文件目录(将来所有资源输出的公共目录)
    path: resolve(__dirname, "build"),
    // 所有资源引入公共路径前缀,例如:'imgs/a.jpg' --> '/imgs/a.jpg'
    publicPath: "/",
    chunkFilename: "js/[name]_chunk.js", // 非入口chunk的名称
    // library: '[name]', // 整个库向外暴露的变量名
    // libraryTarget: 'window' // 变量名添加到哪个上 browser
    // libraryTarget: 'global' // 变量名添加到哪个上 node
    // libraryTarget: 'commonjs'
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: "development",
};

6.3 módulo

const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: './src/index.js',
  output: {
    
    
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      // loader的配置
      {
    
    
        test: /\.css$/,
        // 多个loader用use
        use: ['style-loader', 'css-loader']
      },
      {
    
    
        test: /\.js$/,
        // 排除node_modules下的js文件
        exclude: /node_modules/,
        // 只检查 src 下的js文件
        include: resolve(__dirname, 'src'),
        // 优先执行
        enforce: 'pre',
        // 延后执行
        // enforce: 'post',
        // 单个loader用loader
        loader: 'eslint-loader',
        options: {
    
    }
      },
      {
    
    
        // 以下配置只会生效一个
        oneOf: []
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development'
};

6.4 resolver

const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development',
  // 解析模块的规则
  resolve: {
    
    
    // 配置解析模块路径别名: 优点简写路径 缺点路径没有提示
    alias: {
    
    
      $css: resolve(__dirname, 'src/css')
    },
    // 配置省略文件路径的后缀名
    extensions: ['.js', '.json', '.jsx', '.css'],
    // 告诉 webpack 解析模块是去找哪个目录
    modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
  }
};

6.5 servidor de desarrollo

const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development',
  resolve: {
    
    
    alias: {
    
    
      $css: resolve(__dirname, 'src/css')
    },
    extensions: ['.js', '.json', '.jsx', '.css'],
    modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
  },
  devServer: {
    
    
    // 运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    // 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload
    watchContentBase: true,
    watchOptions: {
    
    
      // 忽略文件
      ignored: /node_modules/
    },
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 5000,
    // 域名
    host: 'localhost',
    // 自动打开浏览器
    open: true,
    // 开启HMR功能
    hot: true,
    // 不要显示启动服务器日志信息
    clientLogLevel: 'none',
    // 除了一些基本启动信息以外,其他内容都不要显示
    quiet: true,
    // 如果出错了,不要全屏提示~
    overlay: false,
    // 服务器代理 --> 解决开发环境跨域问题
    proxy: {
    
    
      // 一旦devServer(5000)服务器接受到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000)
      '/api': {
    
    
        target: 'http://localhost:3000',
        // 发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
        pathRewrite: {
    
    
          '^/api': ''
        }
      }
    }
  }
};

6.6 optimización

const {
    
     resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin')

module.exports = {
    
    
  entry: './src/js/index.js',
  output: {
    
    
    filename: 'js/[name].[contenthash:10].js',
    path: resolve(__dirname, 'build'),
    chunkFilename: 'js/[name].[contenthash:10]_chunk.js'
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'production',
  resolve: {
    
    
    alias: {
    
    
      $css: resolve(__dirname, 'src/css')
    },
    extensions: ['.js', '.json', '.jsx', '.css'],
    modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
  },
  optimization: {
    
    
    splitChunks: {
    
    
      chunks: 'all'
      // 默认值,可以不写~
      /* minSize: 30 * 1024, // 分割的chunk最小为30kb
      maxSiza: 0, // 最大没有限制
      minChunks: 1, // 要提取的chunk最少被引用1次
      maxAsyncRequests: 5, // 按需加载时并行加载的文件的最大数量
      maxInitialRequests: 3, // 入口js文件最大并行请求数量
      automaticNameDelimiter: '~', // 名称连接符
      name: true, // 可以使用命名规则
      cacheGroups: {
        // 分割chunk的组
        // node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
        // 满足上面的公共规则,如:大小超过30kb,至少被引用一次。
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          // 优先级
          priority: -10
        },
        default: {
          // 要提取的chunk最少被引用2次
          minChunks: 2,
          // 优先级
          priority: -20,
          // 如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
          reuseExistingChunk: true
        } 
      }*/
    },
    // 将当前模块的记录其他模块的hash单独打包为一个文件 runtime
    // 解决:修改a文件导致b文件的contenthash变化,在b文件中引入a文件,打包后b文件通过引用a文件的contenthash来引入a文件,修改a文件,a文件的contenthash变化自然会导致b文件发生变化
    runtimeChunk: {
    
    
      name: entrypoint => `runtime-${
      
      entrypoint.name}`
    },
    minimizer: [
      // 配置生产环境的压缩方案:js和css
      new TerserWebpackPlugin({
    
    
        // 开启缓存
        cache: true,
        // 开启多进程打包
        parallel: true,
        // 启动source-map
        sourceMap: true
      })
    ]
  }
};

referencia

Apéndice 1 paquete.json

{
    
    
  "name": "webpack_code",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    
    
    "@babel/core": "^7.8.4",
    "@babel/polyfill": "^7.8.3",
    "@babel/preset-env": "^7.8.4",
    "add-asset-html-webpack-plugin": "^3.1.3",
    "babel": "^6.23.0",
    "babel-loader": "^8.0.6",
    "core-js": "^3.6.4",
    "css-loader": "^3.4.2",
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.0.0",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-import": "^2.20.1",
    "file-loader": "^5.0.2",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "mini-css-extract-plugin": "^0.9.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^1.1.3",
    "terser-webpack-plugin": "^2.3.5",
    "thread-loader": "^2.1.3",
    "url-loader": "^3.0.0",
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3",
    "workbox-webpack-plugin": "^5.0.0"
  },
  "dependencies": {
    
    
    "jquery": "^3.4.1"
  },
  "browserslist": {
    
    
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    
    
    "extends": "airbnb-base",
    "env": {
    
    
      "browser": true
    }
  },
  "sideEffects": [
    "*.css"
  ]
}

Supongo que te gusta

Origin blog.csdn.net/letianxf/article/details/129227015
Recomendado
Clasificación