webpack源码解析一

本文档详细解析了webpack的打包流程,从bin/webpack.js和webpack-cli/bin/cli.js开始,经过lib/webpack.js、WebpackOptionsApply.js、EntryOptionPlugin.js、Compiler和Compilation等关键步骤,直至seal过程和emitAssets生成最终打包文件。文中配以流程图辅助理解,并预告后续将深入探讨各个钩子函数、ModuleFactory和Compilation。
摘要由CSDN通过智能技术生成

先上一张流程图,小伙伴可以跟着这个流程图结合代码往下走:

在这里插入图片描述
再来一张大神画的图:
在这里插入图片描述

图片来源于:细说webpack之流程篇

开始

git clone https://github.com/webpack/webpack.git
yarn
yarn setup

打包

node ./bin/webpack.js

bin/webpack.js

//判断有没有安装webpack-cli,没有话的就提示是否需要安装
const question = `Do you want to install 'webpack-cli' (yes/no): `;
//确定有webpack-cli之后开始执行
require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName]));

webpack-cli/bin/cli.js

//创建compiler编译引擎
let compiler;
			try {
				compiler = webpack(options);
			} catch (err) {
			}
   compiler.run((err, stats) => {}         

整个made过程

lib/webpack.js

const webpack = (options, callback) => {
	let compiler;
		compiler = createCompiler(options);
		watch = options.watch;
		watchOptions = options.watchOptions || {};
	return compiler;
};
//创建编译器
const createCompiler = options => {
    //获取默认的webpack参数
	options = new WebpackOptionsDefaulter().process(options);
	const compiler = new Compiler(options.context);
	compiler.options = options;
    //配置全局api插件比如(fs文件api、infrastructureLogger日志log、)
	new NodeEnvironmentPlugin({
		infrastructureLogging: options.infrastructureLogging
	}).apply(compiler);
    // 执行我们在配置文件中配置的所有插件
	if (Array.isArray(options.plugins)) {
		for (const plugin of options.plugins) {
			if (typeof plugin === "function") {
				plugin.call(compiler, compiler);
			} else {
				plugin.apply(compiler);
			}
		}
	}
    //开启默认的所有插件(比较重要)
	compiler.options = new WebpackOptionsApply().process(options, compiler);
	return compiler;
};

lib/WebpackOptionsApply.js

    //设置默认的一些插件
	process(options, compiler) {
        //入口文件插件注册
        new EntryOptionPlugin().apply(compiler);
        //调用入口文件插件注册钩子函数
		compiler.hooks.entryOption.call(options.context, options.entry);
    }

lib/EntryOptionPlugin.js

module.exports = class EntryOptionPlugin {
	/**
	 * @param {Compiler} compiler the compiler instance one is tapping into
	 * @returns {void}
	 */
	apply(compiler) {
        //注册入口文件插件注册钩子函数
		compiler.hooks.entryOption.tap("EntryOptionPlugin", (context, entry) => {
            
			const applyEntryPlugins = (entry, name) => {
				if (typeof entry === "string") {
                    //调用入口插件
					new EntryPlugin(context, entry, name).apply(compiler);
				} else if (Array.isArray(entry)) {
					for (const item of entry) {
						applyEntryPlugins(item, name);
					}
				}
			};
            //options的entry支持string||array比如:(entry: "src/main.js")||(entry: ["pollyfill.js","src/main.js"])
			if (typeof entry === "string" || Array.isArray(entry)) {
				applyEntryPlugins(entry, "main");
             //options的entry支持object类型比如:(entry:{main: "src/main.js"})
			} else if (typeof entry === "object") {
				for (const name of Object.keys(entry)) {
					applyEntryPlugins(entry[name], name);
				}
                //options的entry支持function类型比如:(entry:()=>"src/main.js")})
			} else if (typeof entry === "function") {
				new DynamicEntryPlugin(context, entry).apply(compiler);
			}
			return true;
		});
	}
};

EntryPlugin.js

apply(compiler) {
       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值