webpack原理
Tapable
webpack最主要的两大模块:负责编译的Compiler和创建bundle的Compilation。而这两个模块都是继承自Tapable。
Tapable内部通过对事件的注册监听,触发webpack生命周期的函数方法。
Compiler
每次执行webpack构建的时候,在webpack内部,会首先实例化一个Compiler对象。调run 方法执行一次完整的编译过程。
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
// 实例化compiler对象
const compiler = webpack(webpackConfig);
// 开始执行
compiler.run(callback);
// 上面两句等价于
webpack(webpackConfig, callback);
Compilation
针对的是随时可变的项目文件,只要文件有改动,Compilation 就会被重新创建。
根据entry提供的入口文件,通过loader将这些文件进行解析,生成chunk,再通过plugin生成最后的bundle;最后根据output,存储到对应的位置。
Compiler和Compilation的关系
- Compiler:代表的是不变的 Webpack 环境,是针对 Webpack 的。
- Compilation:针对的是随时可变的项目文件,只要文件有改动,Compilation 就会被重新创建。
在普通打包模式下,webpack 的 Compiler 和 Compilation 是一一对应的关系; watch 模式下,Webpack 的 Compilation 会因为文件变化而产生多次打包流程,所以 Compiler 和 Compilation 是一对多关系
webpack工作流程
主要由三个阶段:
- 准备阶段:创建compiler和compilation对象;
- 编译阶段:完成modules的解析,生成chunks;
- 产出阶段:根据chunks,生成最终的文件;
module、chunk、bundle
- module
webpack的配置文件中有module字段,通过rules配置处理这些文件的规则。简单理解就是一个文件就是一个module. - chunk
chunk是webpack打包过程中多个module的集合。一个入口文件(看entry),会生成一个chunk。 - bundle
bundle是webpack最终输出的文件。通常,一个chunk产生一个bundle,chunk和bundle是一对多的关系。比如devtool='source-map'时,就会生成两个bundle.
// webpack配置
entry: {
main: __dirname + "/app/main.js",
},
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
},
devtool: 'source-map',