Appearance
初识 webpack
webpack是一个静态的模块化打包工具,为现代的JavaScript应用程序。
我们来对上面的解释进行拆解:
- 打包bundler:webpack可以将帮助我们进行打包,所以它是一个打包工具
- 静态的static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器)
- 模块化module:webpack默认支持各种模块化开发,ES Module、CommonJS、AMD等
- 现代的modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了webpack的出现和发展
结构化理解 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
:编译模式短语,支持development
、production
等值,可以理解为一种声明环境的短语
工具类配置项
除了核心的打包功能之外,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.js
中 module.rules
中允许我们配置多个 loader
。rules
属性对应的值是一个数组。
数组中存放的是一个个的Rule
,Rule
是一个对象,对象中可以设置多个属性: [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
就可以执行了