很多同学看源码分析,一般直接从 src 看起。像 Vuejs
这种项目,目录繁杂,入口都很难找到。不从中拎出几个线头来,很难从全局把握源码的流程。
理解源码是如何构建的,能帮助我们梳理这个过程。
从 package.json
开始
我们关注三个字段:
- “main”: “dist/vue.runtime.common.js”。
默认 require('vue')
, import('vue')
会读取的文件。格式为 commonjs
。
- “module”: “dist/vue.runtime.esm.js”
webpack 2 以上会默认读 module 字段指定的文件。esm 模块方便做 tree shaking。
- “scripts”
现在很多的包使用 npm scripts 来做构建流程脚本。我们可以看到 vue 内部有许多研发流程脚本在 scripts字段内, 我们关注 build 部分代码:
1 | "build": "node scripts/build.js", |
会发现所有构建相关的逻辑都在 scripts/build.js
内。
rollup
在分析 scripts/build.js
脚本之前,我们先来简单介绍一下 rollup。
业界有一种说法:webpack 适合打包应用程序,而 rollup 适合打包应用库。rollup 是一个以 利用 es 模块特性,treeshaking 起家的库,相比webpack ,可以打包出各种模式(cmd, umd, es)的类库。
而 vue 的源码就是用 es 模块编写的,它的构建脚本整个都是围绕如何组合 rollup 的配置。
打包工具的通常关注的配置是,入口是什么,输出文件放哪里,输出什么格式,用什么插件,不同的环境怎么处理。vue 的构建脚本并不例外。
构建脚本分析
如上所诉,vue 的构建脚本就是围绕 rollup ,做一些自定义配置。相关代码在:
scripts/build.js
主构建流程scripts/alias.js
文件路径 aliasscripts/config.js
生成 rollup 配置
我们简要分析一下这几个文件。在 scripts/build.js
中:
1 | function buildEntry (config) { |
buildEntry 方法暴露了 vue 的构建流程是依赖 rollup 的。
在 scripts/config.js
中:
1 | const resolve = p => { |
以生成的 es 模块为例,他的入口文件为 resolve('web/entry-runtime.js')
。
config 的 resolve 遇到在 alias 中的文件会特殊处理。alias 定义在 scripts/alias.js
。
1 | const resolve = p => path.resolve(__dirname, '../', p) |
这些alias 会贯穿整个 vue 源码中。resolve(web/entry-runtime.js)
最终地址位于 src/platforms/web/entry-runtime.js。
1 | Vue 的 入口 都在 plaforms 的 web 、 weex、sever 下。具体参考 scripts/config.js。 |
找到这个入口文件之后,我们就拿到了分析源码的一条绳。从此文件开始,便可以分析 Vue 的源码是如何工作的。
参考资料
ISSUE
有问题,来 GitHub 一起讨论。