最接地气的webpack源码解析(二)

1,424 阅读2分钟

承接上篇讲解到了webpack-cli/bin/cli.js文件中的compiler.run(),如果没有看过上篇文章的小伙伴建议先回过头简单过一遍,最接地气的webpack源码解析(一)

将按照主线讲解webpack执行入口、构建前准备阶段、编译构建阶段、构建后优化阶段、文件输出阶段这五部分,本篇主要讲解构建前的准备阶段,由于在webpack-cli/bin/cli.js中最后是引入并且实例化webpack,const webpack = require("webpack");,说明构建前的准备阶段主要是在webpack文件夹内。

这里说明一下针对cjs的require语法,引入的其实是依赖包里的入口文件,也就是package.json里main字段对应的文件"main": "lib/webpack.js"

webpack/lib/webpack.js

const Compiler = require("./Compiler");

const webpack = (options, callback) => {
    options = new WebpackOptionsDefaulter().process(options);

    compiler = new Compiler(options.context);
    compiler.options = options;
    new NodeEnvironmentPlugin({
        infrastructureLogging: options.infrastructureLogging
    }).apply(compiler);
    
    if (options.plugins && Array.isArray(options.plugins)) {
        for (const plugin of options.plugins) {
            if (typeof plugin === "function") {
                plugin.call(compiler, compiler);
            } else {
                plugin.apply(compiler);
            }
	}
    }
    compiler.hooks.environment.call();
    compiler.hooks.afterEnvironment.call();
    compiler.options = new WebpackOptionsApply().process(options, compiler);
    
    return compiler;
}
exports = module.exports = webpack;

首先根据配置项参数初始化webpack的默认配置WebpackOptionsDefaulter(),然后使用options实例化Complier得到解析器对象,然后初始化构建过程的node环境NodeEnvironmentPlugin,注册用户自定义的各个插件,再注册webpack内置的各个插件WebpackOptionsApply(),最后返回compiler。

这里主要是进行webpack构建前的准备阶段,数据初始化和环境搭建,特别说明一下WebpackOptionsApply()这个函数内做了很多内置插件的注册工作

// webpack/lib/WebpackOptionsApply.js

class WebpackOptionsApply extends OptionsApply {
    new EntryOptionPlugin().apply(compiler);
    compiler.hooks.entryOption.call(options.context, options.entry);

    compiler.hooks.afterResolvers.call(compiler);
}
module.exports = WebpackOptionsApply;

这部分需要特别点出两个钩子,entryOptionafterResolvers分别表示入口配置和路径解析,当这两部分工作处理完成之后,就可以真正开始最重要的编译构建阶段。

webpack构建流程中关键节点钩子

下面是本次分享主题最干货的部分,重点看这里!重点看这里!重点看这里!

webpack构建流程2.0.png

提前剧透一下后面几章讲要分享的内容,该流程图是笔者借鉴网课的基础上修改得到的,里面的每个关键节点都是构建过程中的钩子,下一张将介绍从run->make->buildModule->normal-module-loader->program的过程,也是本次分享里最重要的一部分,webpack的核心构建过程。