Skip to content

初识 webpack

webpack是一个静态的模块化打包工具,为现代的JavaScript应用程序。

我们来对上面的解释进行拆解:

  • 打包bundler:webpack可以将帮助我们进行打包,所以它是一个打包工具
  • 静态的static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器)
  • 模块化module:webpack默认支持各种模块化开发,ES Module、CommonJS、AMD等
  • 现代的modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了webpack的出现和发展

image-20240821100136271

结构化理解 webpack 配置项

可以将webpack 的编译流程简化为:

编译流程

输入 -> 模块处理 -> 后处理 -> 输出

  • 输入:从文件系统读入代码文件;
  • 模块递归处理:调用 Loader 转译 Module 内容,并将结果转换为 AST,从中分析出模块依赖关系,进一步递归调用模块处理过程,直到所有依赖文件都处理完毕;
  • 后处理:所有模块递归处理完毕后开始执行后处理,包括模块合并、注入运行时、产物优化等,最终输出 Chunk 集合;
  • 输出:将 Chunk 写出到外部文件系统;

流程类配置项

与打包流程强相关的配置项有:

  • 输入输出:
    • entry:用于定义项目入口文件,Webpack 会从这些入口文件开始按图索骥找出所有项目文件;
    • context:项目执行上下文路径;
    • output:配置产物输出路径、名称等;
  • 模块处理:
    • resolve:用于配置模块路径解析规则,可用于帮助 Webpack 更精确、高效地找到指定模块
    • module:用于配置模块加载规则,例如针对什么类型的资源需要使用哪些 Loader 进行处理
    • externals:用于声明外部资源,Webpack 会直接忽略这部分资源,跳过这些资源的解析、打包操作
  • 后处理:
    • optimization:用于控制如何优化产物包体积,内置 Dead Code Elimination、Scope Hoisting、代码混淆、代码压缩等功能
    • target:用于配置编译产物的目标运行环境,支持 web、node、electron 等值,不同值最终产物会有所差异
    • mode:编译模式短语,支持 developmentproduction 等值,可以理解为一种声明环境的短语

工具类配置项

除了核心的打包功能之外,Webpack 还提供了一系列用于提升研发效率的工具,大体上可划分为:

  • 开发效率类:
    • watch:用于配置持续监听文件变化,持续构建
    • devtool:用于配置产物 Sourcemap 生成规则
    • devServer:用于配置与 HMR 强相关的开发服务器功能
  • 性能优化类:
    • cache:Webpack 5 之后,该项用于控制如何缓存编译过程信息与编译结果
    • performance:用于配置当产物大小超过阈值时,如何通知开发者
  • 日志类:
    • stats:用于精确地控制编译过程的日志内容,在做比较细致的性能调试时非常有用
    • infrastructureLogging:用于控制日志输出方式,例如可以通过该配置将日志输出到磁盘文件
  • 等等

简单的案例理解配置逻辑

文件目录结构

bash
.
├── src
|   └── index.js
└── webpack.config.js

进行 webpack 配置

js
// webpack.config.js
const { resolve } = require('path')

module.exports = () => ({
  mode: 'none',
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: '[name].js',
    path: resolve(__dirname, './dist')
  },
})

mode:有development(开发环境)、production(生产环境)和none三个选项

./src/index.js 就是项目的入口文件,输出内容会在当前配置文件下新建一个 dist 目录,存放打包后的文件。

需要安装 webpack、webpack-cli,然后执行 webpack 命令 即可打包

输入后的结果

bash
.
├── dist
|   └── main.js
├── src
|   └── index.js
└── webpack.config.js

这个案例中只有js文件,但在实际开发中,往往是有很多其他文件的,比如 css,png,svg....等等等。需要借助 Loader 来识别它们(根据文件的不同使用不同的loader来解析)

Loader 和 Plugin

Loader 可以用于对模块的源代码进行转换

Plugin可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等

Loader 的配置方式

webpack.config.jsmodule.rules 中允许我们配置多个 loaderrules属性对应的值是一个数组。

数组中存放的是一个个的RuleRule是一个对象,对象中可以设置多个属性: [Rule]

  • test属性:用于对 resource(资源)进行匹配的,通常会设置成正则表达式;
  • use属性:对应的值时一个数组:[UseEntry]
    • UseEntry是一个对象,可以通过对象的属性来设置一些其他属性
      • loader:必须有一个 loader属性,对应的值是一个字符串;
      • options:可选的属性,值是一个字符串或者对象,值会被传入到loader中;
      • query:目前已经使用options来替代;
    • 传递字符串(如:use: [ 'style-loader' ])是 loader 属性的简写方式(如:use: [ { loader: 'style-loader'} ]);
  • loader属性: Rule.use: [ { loader } ] 的简写。

Plugin 的配置方式

plugin 配置比较简单,它是一个数组,将所需插件放进数组即可

js
module.exports = () => ({
  plugins: [
    new MiniCssExtractPlugin(),
    new HtmlWebpackPlugin()
  ]
})

常见的一些Plugin

  • CleanWebpackPlugin:重新打包时,自动清除打包文件夹。也可以不借助该插件,直接在 output 中设置 clean 属性 为 true,可以达到同样效果
  • HtmlWebpackPlugin: 对 index.html 进行打包处理(根据 ejs 的一个模板生成),也可以自定义 html 模板
  • DefinePlugin:webpack自带,用于定义全局变量
  • CopyWebpackPlugin:用于复制文件,比如在vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中

指定配置文件运行

如果我们将webpack.config.js 的名字改为 wp.config.js,在package.json 中可以修改脚本,也可以在命令行直接运行 webpack --config wp.config.js

json
{
    "script": {
        "build": "webpack --config wp.config.js"
    }
}

直接 npm run build 就可以执行了

Released under the MIT License.