webpack学习--流程篇

webpack流程小解

这篇主要小小的介绍webpack的强大的强大的强大的强大的编译过程。

前言

在介绍正式编译过程之前,首先明确webpack是一个事件流驱动的组件,通过事件注册和事件触发完成整个编译过程。其中事件流的实现主要是依赖Tapable插件,Tapable的实现也很简单。

//函数只有一个是参数,私有属性_plugins,用于记录注册的事件,事件名:回调函数
function Tapable() {
	this._plugins = {};
}

//事件注册  往_plugins中注册事件
Tapable.prototype.plugin = function plugin(name, fn) {
	if(Array.isArray(name)) {
		name.forEach(function(name) {
			this.plugin(name, fn);
		}, this);
		return;
	}
	if(!this._plugins[name]) this._plugins[name] = [fn];
	else this._plugins[name].push(fn);
};

//其中一个事件触发的函数
Tapable.prototype.applyPlugins = function applyPlugins(name) {
	if(!this._plugins[name]) return;
	var args = Array.prototype.slice.call(arguments, 1);
	var plugins = this._plugins[name];
	for(var i = 0; i < plugins.length; i++)
		plugins[i].apply(this, args);
};

然后weback通过组合继承的方式继承Tapable

var Tapable = require("tapable");

function Compiler() {
	Tapable.call(this);

	...
}

Compiler.prototype = Object.create(Tapable.prototype);
Compiler.prototype.constructor = Compiler;

知道事件流机制之后,再来理解webpack的编译过程,大致如下图

流程详解

官方文档:

complier钩子:https://www.webpackjs.com/api/compiler-hooks/

compilation钩子:https://www.webpackjs.com/api/compilation-hooks/

0. 部分名词解释

  • loader:能转换各类资源,并处理成对应模块的加载器。loader 间可以串行使用。
  • chunk:code splitting 后的产物,也就是按需加载的分块,装载了不同的 module。
  • Complier: webpack的完整编译过程,通过Complier.run方法开始执行编译,然后调用Complier.compile创建出compilation对象。
  • Compilation:webpack的每次编译过程,由Complier.compile创建,多个入口会生成多个Compilation,其中包含了当前编译过程的入口和出口以及依赖等等。

1. shell 与 config 解析

     这一步使用了nodejs的library中的optimist工具

var optimist = require("optimist");

optimist
  .boolean("json").alias("json", "j").describe("json")
  .boolean("colors").alias("colors", "c").describe("colors")
  .boolean("watch").alias("watch", "w").describe("watch")
  ...


==》

// webpack --hot -w
{
  hot: true,
  profile: false,
  watch: true,
  ...
}

2. config合并于插件加载

将配置文件中的各项配置拷贝到options对象中,并根据启动命令中的args加载对应的插件

3. 编译与构建流程

开始初始化webpack,生成complier对象,通过complier的run方法开始进行真正的编译过程,以下是编译过程中重要的事件节点

  • compile 开始编译
  • make 从入口点分析模块及其依赖的模块,创建这些模块对象
  • build-module 构建模块
  • after-compile 完成构建
  • seal 封装构建结果
  • emit 把各个chunk输出到结果文件
  • after-emit 完成输出

 a). 生成Compliation对象

Compliation两个作用,一是负责整个打包过程,包含了每个构建环节及输出环节所对应的方法。二是该对象内部存放着所有module,chunk,生成的asset以及用来生成最后打包文件的template信息。

 b)编译和构建主流程

先找到入口js文件,开始构建模块

  • 调用各loader处理模块
  • 解析经loader处理后的源文件生成抽象语法树AST
  • 遍历AST,递归处理依赖的module,重复上述编译过程

 4. 打包输出

所有模块build完成之后,webpack会监听seal事件调用各插件对构建后进行封装,逐次对每个module和chunk进行整理,生成编译后的源码,合并,拆分,生成hash

 

你可能感兴趣的:(前端框架相关,JavaScript相关)