webpack设计理念
Webpack 本质上是一个函数,它接受一个配置信息作为参数,执行后返回一个 compiler 对象,调用 compiler 对象中的 run 方法就会启动编译。run 方法接受一个回调,可以用来查看编译过程中的错误信息或编译信息
核心思想
- 首先,根据配置信息(webpack.config.js)找到入口文件(src/index.js)
- 到入口文件所依赖的模块,并收集关键信息:比如路径、源代码、它所依赖的模块等
- Loader 系统 本质上就是接收资源文件,并对其进行转换,最终输出转换后的文件
- 根据上一步得到的信息,生成最终输出到硬盘中的文件(dist): 包括 modules 对象、require 模版代码、入口执行文件等
除此之外,打包过程中也有一些特定的时机需要处理,比如:
- 在打包前需要校验用户传过来的参数,判断格式是否符合要求
- 在打包过程中,需要知道哪些模块可以忽略编译,直接引用 cdn 链接
- 在编译完成后,需要将输出的内容插入到 html 文件中
- 在输出到硬盘前,需要先清空 dist 文件夹
这个时候需要一个可插拔的设计,方便给社区提供可扩展的接口 —— Plugin 系统
, 本质上就是一种事件流的机制,到了固定的时间节点就广播特定的事件,用户可以在事件内执行特定的逻辑,类似于生命周期
架构设计
需要建立一套事件流的机制来管控整个打包过程,大致可以分为三个阶段:
- 打包开始前的准备工作
- 打包过程中(也就是编译阶段)
- 打包结束后(包含打包成功和打包失败)
实现方式:Tapable
具体实现:
- 搭建结构,读取配置参数
- 用配置参数对象初始化 Compiler 对象
- 挂载配置文件中的插件
- 执行 Compiler 对象的 run 方法开始执行编译
- 根据配置文件中的 entry 配置项找到所有的入口
- 从入口文件出发,调用配置的 loader 规则,对各模块进行编译
- 找出此模块所依赖的模块,再对依赖模块进行编译
- 等所有模块都编译完成后,根据模块之间的依赖关系,组装代码块 chunk
- 把各个代码块 chunk 转换成一个一个文件加入到输出列表
- 确定好输出内容之后,根据配置的输出路径和文件名,将文件内容写入到文件系统