什么是 webpack

是一个静态打包工具

核心思想是:静态分析模块之间的依赖关系,然后将这些模块按一定规则打包成一个或多个文件

解决了以下问题:

  • 代码模块化和统一管理
  • 自动处理各模块的依赖
  • 热更新,提高开发效率
  • 代码拆分、压缩等

构建流程

初始化配置 从 entry 开始分析模块依赖 通过 loader 进行各个文件的编译 build 完成输出到 dist 目录

Loader

是什么:

Webpack 中的文件加载器,是一个函数。运行在打包文件之前。

作用:

Webpack 本身默认只能理解处理 .js.json 文件,Loader 的作用是让 Webpack 能够处理其他类型的文件,通过链式调用对资源文件进行转换和处理

使用:

写在 module.rules 属性中,常见的有:

  • css-loader:用于加载 css
  • style-loader:用于将 css 添加到 DOM 中的 <style> 标签中
  • sass-loader:处理 sass 文件
  • file-loader:将文件打包到输出目录中
  • url-loader:将文件转换为内联的 base64

Plugin

是什么:

Webpack 中的插件,是一个具有 apply 方法的函数。在整个编译周期都起作用。webpack 生命周期中的各个环节会提供钩子 (hook),可以在这些生命周期节点透过 Plugin 来做额外操作,进而拓展 webpack 的功能。

  1. 一个 JavaScript 命名函数
  2. 在插件函数的 prototype 上定义一个 apply 方法
  3. 指定一个绑定到 webpack 自身的事件钩子
  4. 处理 webpack 内部实例的特定数据
  5. 功能完成后调用 webpack 提供的回调

作用:

用于对 Webpack 的构建流程进行功能扩展

使用:

写在 plugins 属性中,常见的有:

  • HtmlWebpackPlugin:打包结束后,⾃动生成⼀个 html 文件,并把打包生成的 js 模块引⼊到该 html 中
  • CleanWebpackPlugin:构建前清理输出目录,避免旧文件残留
  • TerserWebpackPlugin:压缩 JS 代码

Loader 和 Plugin 区别

特性LoaderPlugin
主要作用转换文件内容(如转译、预处理)扩展构建流程(优化、资源管理、注入环境变量等)
执行时机在模块加载时(文件转换为模块时)在整个构建生命周期(从初始化到输出)的各个阶段
配置方式通过 module.rules 数组配置通过 plugins 数组配置(需要 new 实例化)
典型场景处理 JS/CSS/图片等文件转译生成 HTML、压缩代码、提取 CSS 等全局操作
依赖关系针对特定文件类型(如 .scss )不依赖文件类型,可干预整个构建流程

tree-shaking

一种代码静态分析技术,用于消除 JavaScript 应用中的未使用代码(Dead Code)。通过移除这些未使用的代码,可以减少最终打包文件的体积,从而提高应用的加载速度和性能

原理

静态分析:依赖 ES6 Module 功能(不能是 CommonJS 因为是它动态的运行时加载)

开启步骤

  1. 关闭 babel 的模块语法转换
  2. 在 @babel/preset-env 配置中 modules 设置为 false,这样 babel 就不会将我们写的 es6 Module 的导入方式进行转换(tree-shaking 依赖 es6 的 Module 语法)
  3. 设置 mode 为 production
  4. 确保 usedExports 为 true(默认为 true)
  5. 必要的情况下指定 sideEffects

实践

  • usedExports:开启后会标记哪些代码没有被使用,之后通过 Terser 来进行优化
  • sideEffects:在 package.json 中配置哪些文件不进行优化,告诉 webpack 哪些模块有副作用(代码会执行一些特殊的逻辑如定义全局变量等,不能仅仅通过 export 来判断这段代码的使用),避免被错误删除

提高构建速度

  • 给一些常用的路径起别名,减少查找过程
  • 使用 SplitChunksPlugin 代码分割,将公共代码抽取出来,减少重复打包
  • 使用缓存 cache
  • 有一些多线程的配置,并行构建