likes
comments
collection
share

浅析webpack源码

作者站长头像
站长
· 阅读数 87

写在前面

webpack源码自己研究了几个星期,而且在团队内部也做了分享,之前一直没有在思否上写过文章,后面感觉思否相对于CSDN文章质量更高,因此转战思否,后面争取每周更新一篇较高质量文章,期待自己不断取得提升。

1、webpack的作用

webpack作为前端十分重要的一种打包工具,其主要作用用一句话概括:

  • 将代码(包括css, ts, vue,sass)基于依赖关系打包成浏览器可以运行的多个bundle.js

基于该目的,webpack必须要实现四件事情:

  • 基于acorn搜集模块依赖;
  • 将所有文件基于loader转成浏览器可以运行的js
  • 在打包整个生命周期过程中做很多事情(基于plugin实现)
  • 最后打包(tree-shaking等)成多个bundle.js

2、tapable和acorn

浅析webpack源码

粘贴一段源码,可以看到在整个编译过程多次出现类似的写法,并且在两个钩子之间并没有找到对应的实现代码,那具体钩子之中是做了什么呢?

这个时候就需要介绍下tapable库

2.1 tapable 是一个类似于nodejs 的EventEmitter 的库, 主要是控制钩子函数的发布与订阅,控制着webpack的插件系.webpack的本质就是一系列的插件运行.

浅析webpack源码

  • 钩子类型分为四种:

1、基本的钩子

2、waterfall: 会调用每个tap传入的函数,同时将每个函数的返回值给下一个函数

3、bail: 允许更早的退出,当某个tap的函数返回任何值,该钩子会停止其他函数执行;

4、loop: 若某个函数有返回值,则会循环之前执行的事件

在webpack中使用最多的钩子是 syncHook(同步钩子)和 AsyncSeriesHook(异步串行钩子)

  • 钩子的三种注册方式(包含名称和对应的回调):

    1、tap: 注册同步钩子

    2、tapAsync: 注册带callback回调的异步钩子 (用的最多)

    3、tapPromise: 注册带promise回调的异步钩子

  • 对应的三种调用方式

    1、 call : 调用注册的同步钩子;

    2、callAsync: 调用注册的带有callback回调的异步钩子

    3、promise: 调用注册的带promise回调的异步钩子

看个例子

  • webpack中beforeCompile钩子的声明,插件注册和调用

浅析webpack源码

浅析webpack源码

浅析webpack源码

  • 基于在webpack各个生命周期钩子中声明的插件,实现webpack的整个功能
  • 看下webpack各个声明周期钩子: https://webpack.js.org/api/co...
  • 补充一个小点: 观察者模式和发布订阅模式的区别:

    观察者模式是松耦合,只有观察者和被观察者两者(比如某个值变化,调用某个函数);

    发布订阅模式不存在耦合,有发布者,订阅者和经纪人(broker)

2.2 对于acorn

  • acorn是一个库,实现对js的解析,将其转换成ast, 转换后实现对依赖搜集浅析webpack源码

3、webpack运行各阶段

  • 首先看下Compiler和Compilation的区别

Compiler 对象: 包含了 Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;

Compilation 对象:包含了当前的模块资源、编译生成资源、变化的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 Compilation 将被创建。Compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。

Compiler 和 Compilation 的区别在于:Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只是代表了一次新的编译。

  • 找了一张网图,对各流程梳理

浅析webpack源码

  • 在依赖搜集,loader对代码处理,均在make阶段实现浅析webpack源码

  • 几个要点:

1、webpack运行是调用compiler.run

2、webpack基于tapable实现的发布订阅模式构建(万物即插件)

3、ast是基于acron库实现

4、loader处理和依赖搜集是在make阶段实现

5、整个阶段会经历: environment,afterEnvironment,beforeRun,run, beforeCompile,Make, afterCompile 等多个阶段


以上就是对webpack源码浅析,对于大体流程做了一个梳理,但是更为精细的流程还是需要去看各插件的源码才行

转载自:https://segmentfault.com/a/1190000040531288
评论
请登录