Webpack打包核心工作原理和打包结果运行原理浅析(非常浅)
在 Webpack 4 以后,很多配置都已经被简化了,整体上的基本使用并不复杂,在这种配置并不复杂的前提下,对它的掌握程度主要就体现在了是否能够理解它的工作机制和原理上了。
打包核心工作原理
Webpack 官网开始的首页,就已经描述了它的工作原理。在 Webpack 的思想中,像 JS、CSS、图片、字体等,都属于一个模块。Webpack 可以通过打包,将它们最终聚集到一起。
Webpack 在整个打包的过程中:
通过 Loader 处理特殊类型资源的加载,例如加载样式、图片
通过 Plugin 实现各种自动化的构建任务,例如自动压缩
具体打包的过程:Webpack 启动后,会根据我们的配置,找到项目中的某个指定文件(一般都会是一个 JS 文件)作为入口。然后顺着入口文件中的代码,根据代码中出现的 import(ES Modules)或者是 require(CommonJS)之类的语句,解析推断出来这个文件所依赖的资源模块,然后再分别去解析每个资源模块的依赖,周而复始,最后形成整个项目中所有用到的文件之间的依赖关系树。
整个打包过程中,Loader 机制起了很重要的作用(没有 Loader 的话,就无法实现各种各样类型的资源文件加载),对于依赖模块中无法通过 JavaScript 代码表示的资源模块,例如图片或字体文件,一般的 Loader 会将它们单独作为资源文件拷贝到输出目录中,然后将这个资源文件所对应的访问路径作为这个模块的导出成员暴露给外部。
自定义插件机制(plugins),它并不会影响 Webpack 的核心工作过程,只是 Webpack 为了提供一个强大的扩展能力,它为整个工作过程的每个环节都预制了一个钩子,也就是说我们可以通过插件往 Webpack 工作过程的任意环节植入一些自定义的任务,从而扩展 Webpack 打包功能以外的能力(目的在于解决 loader 无法实现的其他事)。
打包结果运行原理
将 Webpack 工作模式设置为 none,这样 Webpack 就会按照最原始的状态进行打包,所得到的代码更容易理解和阅读。(VSCode 中折叠代码的快捷键是 Ctrl + K,Ctrl + 0 )
整体生成的代码其实就是一个立即执行函数,这个函数是 Webpack 工作入口(webpackBootstrap),它接收一个 modules 参数,调用时传入了一个数组。
展开这个数组,里面元素的函数对应的就是我们源代码中的模块,也就是说每个模块最终被包裹到了这样一个函数中,从而实现模块私有作用域
展开 Webpack 工作入口函数(我在注释旁稍微加了下翻译)
最开始定义了一个 installedModules 对象用于存放或者缓存加载过的模块,然后定义了一个 require 函数(这个函数是用来加载模块的),再往后就是在 require 函数上挂载了一些其他的数据和工具函数。
这个函数执行到最后调用了 require 函数,传入的模块 id 为 0,开始加载模块。模块 id 实际上就是模块数组的元素下标,也就是说这里开始加载源代码中所谓的入口模块。
最后,如果想更好的稍微理解下打包结果的执行过程,可以把它运行到浏览器中,然后通过开发者工具调试一下。
发表评论 (审核通过后显示评论):