# webpack工作原理

# 基本概念

要了解原理之前,必须先掌握以下的一些核心概念:

  • config:配置,webpack 初始化的参数。
  • entry:入口,开始构建时的 js 文件入口。
  • module:模块,一个模块对应一个文件,从 entry 入口开始,递归找出所有依赖的模块。
  • chunk:代码块,一个 chunk 由多个模块组合而成,用于代码合并与分割。
  • loader:文件资源转换器,将模块的原内容翻译成 webpack 可以理解的新内容。
  • plugin:扩展插件,在 webpack 构建流程中的特定时机会广播对应的事件,插件可以监听这些事件的发生,在特定的时机做对应的事情。

# 工作流程

  1. 初始化参数:从 webpack.config.js 和 shell 脚本中读取合并参数,得到最终参数。
  2. 开始编译(compile):用上一步对象来初始化 Comiler 对象,加载所有配置插件,通过执行对象的 run 方法开始进行编译。
  3. 确定入口:根据配置 entry 找到所有入口文件。
  4. 编译模块:从入口文件出发,调用所有配置 loader 对模块进行翻译,再找出模块依赖的模块,递归本步骤直到所有入口依赖文件都经过处理。
  5. 完成编译模块:经过第四步,得到每个模块被翻译后的最终内容和他们之间的依赖关系。
  6. 输出资源:根据入口和模块依赖之间的关系,组装成一个个包含多个模块的 chunk,再将每个 chunk 转换成一个单独的文件加入到输出列表,这是可以修改输出内容的最后机会。
  7. 输出完成:确定好输出内容后,根据配置输出的路径和文件名,将文件写入文件系统。

在以上过程中,webpack 会在特定的时间点广播特定的事件,插件监听事件并执行相应的逻辑,并且插件可以调用webpack 提供的 api 改变 webpack 的运行结果。

流程中的更多细节可参考此链接(opens new window)

# loader 和 plugin 的区别

  • loader 用于加载某些资源文件。因为 webpack 只能理解 javaScript 和 json 文件,对于其他资源例如 css,图片,或者其他的语法集,比如 jsx, coffee,是没有办法加载的。 这就需要对应的 loader 将资源转化,加载进来。从字面意思也能看出,loader 是用于加载的,它作用于一个个文件上。
  • plugin 用于扩展 webpack 的功能。它直接作用于 webpack,扩展了它的功能。当然 loader 也是变相的扩展了 webpack,但是它只专注于转化文件(transform)这一个领域。而 plugin 的功能更加的丰富,而不仅局限于资源的加载。

就是上面说的前者用于翻译文件资源,后者用于在特定的时间做一些特定的事情。

# 参考文章

https://segmentfault.com/a/1190000017890529