「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」
前言
我们书接上回,继续进行webpack的源码学习。回顾一下上一章的内容,我们看到webpack初始化的时候,执行了runCli方法,进行了一系列webpack-cli的操作,然后又回到了webpack的源码中。
源码学习
webpack 方法
webpack方法接收两个参数:options和callback。
options是webpack-cli中对webpack命令参数的整合。而如果传入callback的时候,会在webpack打包成功或者失败的时候,将结果或者错误信息传入callback并执行。
compiler.run((err, stats) => {
compiler.close(err2 => {
callback(err || err2, stats);
});
});
这里有点需要提一下,不知道大家有没有写过或者见过webpack手动调用的实现,通过手动创建webpack并执行run方法。大体代码如下:
webpack(config).run((err, stats) => {
return err ? reject(err) : resolve(stats);
})
这个run方法中传入的callback其实跟compiler中接收的callback是同一个回调方法。
在这个方法中,我们可以了解到一个知识点:如果执行webpack的时候,传入了--watch,或者在webpack的配置文件中配置了watch:true的时候,说明webpack打包的时候开启了观察模式。
create方法
在create方法中,首先做了options参数的校验。然后做了options参数的处理。通过这个方法我们可以发现,webpack通过判断options的数据类型来判断webpack是单配置还是多配置。如果options是数组类型,通过调用createMultiCompiler方法来处理;如果options是对象类型通过调用createCompiler方法来处理。
在createMultiCompiler中,通过遍历options调用createCompiler方法来处理每一组配置。
const compilers = childOptions.map(options => createCompiler(options));
createCompiler方法
在createCompiler方法中,首先会对options参数进行格式化处理(如果没有传入options,则会完全采用webpack内置的配置),然后通过通过实例化Compiler方法来创建webpack编译器,最后有一点比较特殊的是对plugin插件进行了挂载处理。
这里有一点比较奇怪的地方,按照常理createCompiler方法中,最终目的就是创建compiler,但是,在最后的时候做的是plugin插件处理,而且通过这里我们可以发现plugins配置的方式,是以数组的形式配置的。
for (const plugin of options.plugins) {
if (typeof plugin === "function") {
plugin.call(compiler, compiler);
} else {
plugin.apply(compiler);
}
}
在这个方法中,我们初步接触到了tapable,也就是大家常说的webpack的钩子。
compiler.hooks.environment.call();
compiler.hooks.afterEnvironment.call();
...
compiler.hooks.initialize.call()
结语
接下来就是webpack的核心——Compiler,在Compiler的实体类中我们就会接触到webpack打包编译的核心流程。在理解Compiler之前,需要理解一下tapable。
好了,这一期的源码分析到这里就结束了。欢迎小伙伴们在下方留言讨论。