Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 源码学习(一) - 目录结构与构建 #8

Open
zhuping opened this issue Apr 8, 2019 · 0 comments
Open

Vue 源码学习(一) - 目录结构与构建 #8

zhuping opened this issue Apr 8, 2019 · 0 comments

Comments

@zhuping
Copy link
Owner

zhuping commented Apr 8, 2019

Vue 已然成为目前最流行的主流框架之一,现在出去找工作,如果说不会使用 Vue,似乎有些说不过去。我平时工作中也会使用到 Vue,但就使用率来说,只能算是用到了些常用的api,对于一些高阶用法或者是技术细节,了解甚少,遇到问题还是需要反复的去查询文档或者寻求他人帮助。所以想要彻底的搞懂 Vue,还是要从它的源码入手。

在此之前,我也看过很多网上别人写的关于源码分析的文章,不过如果不是按照自己的思路去一行一行的分析过,很容易遗忘掉。接下来我会出一些根据自己的理解,阅读 Vue 源码的系列文章,本人水平有限,欢迎指出。

声明:Vue 版本为:v2.6.10

目录结构

我们先来看下 Vue 的目录结构,了解下大致的文件分布:

├── scripts ------------------------------- 构建相关的文件,一般情况下我们不需要动
   ├── git-hooks ------------------------- 存放git钩子的目录
   ├── alias.js -------------------------- 别名配置
   ├── config.js ------------------------- 生成rollup配置的文件
   ├── build.js --------------------------  config.js 中所有的rollup配置进行构建
   ├── ci.sh ----------------------------- 持续集成运行的脚本
   ├── release.sh ------------------------ 用于自动发布新版本的脚本
├── dist ---------------------------------- 构建后文件的输出目录
├── examples ------------------------------ 存放一些使用Vue开发的应用案例
├── flow ---------------------------------- 类型声明,使用开源项目 [Flow](https://flowtype.org/)
├── packages ------------------------------ 存放独立发布的包的目录
├── test ---------------------------------- 包含所有测试文件
├── src ----------------------------------- 这个是我们最应该关注的目录,包含了源码
   ├── compiler -------------------------- 编译器代码的存放目录,将 template 编译为 render 函数
   ├── core ------------------------------ 存放通用的,与平台无关的代码
      ├── observer ---------------------- 响应系统,包含数据观测的核心代码
      ├── vdom -------------------------- 包含虚拟DOM创建(creation)和打补丁(patching)的代码
      ├── instance ---------------------- 包含Vue构造函数设计相关的代码
      ├── global-api -------------------- 包含给Vue构造函数挂载全局方法(静态方法)或属性的代码
      ├── components -------------------- 包含抽象出来的通用组件
   ├── server ---------------------------- 包含服务端渲染(server-side rendering)的相关代码
   ├── platforms ------------------------- 包含平台特有的相关代码,不同平台的不同构建的入口文件也在这里
      ├── web --------------------------- web平台
         ├── entry-runtime.js ---------- 运行时构建的入口,不包含模板(template)到render函数的编译器,所以不支持 `template` 选项,我们使用vue默认导出的就是这个运行时的版本。大家使用的时候要注意
         ├── entry-runtime-with-compiler.js -- 独立构建版本的入口,它在 entry-runtime 的基础上添加了模板(template)到render函数的编译器
         ├── entry-compiler.js --------- vue-template-compiler 包的入口文件
         ├── entry-server-renderer.js -- vue-server-renderer 包的入口文件
         ├── entry-server-basic-renderer.js -- 输出 packages/vue-server-renderer/basic.js 文件
      ├── weex -------------------------- 混合应用
   ├── sfc ------------------------------- 包含单文件组件(.vue文件)的解析逻辑,用于vue-template-compiler包
   ├── shared ---------------------------- 包含整个代码库通用的代码
├── package.json -------------------------- 不解释
├── yarn.lock ----------------------------- yarn 锁定文件
├── .editorconfig ------------------------- 针对编辑器的编码风格配置文件
├── .flowconfig --------------------------- flow 的配置文件
├── .babelrc ------------------------------ babel 配置文件
├── .eslintrc ----------------------------- eslint 配置文件
├── .eslintignore ------------------------- eslint 忽略配置
├── .gitignore ---------------------------- git 忽略配置

了解每个模块的具体功能,对后面源码的阅读也有帮助。

构建方式

根据 package 中可执行脚本命令可以看出,vue 有三种构建方式,不同的方式采取不同的打包方式,对应的分别是 UMDCommonJS 以及 ES Module

"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
"dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",
"dev:esm": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-esm",

打开 scripts/config.js 文件,我们可以看到 cjs 模块分别输出了 运行时版 以及 完整版 两个版本,es 模块也做了同样的事情,我们观察运动时版与完整版本的区别:

运行时的入口文件名字为: entry-runtime.js

完整版的入口文件名字为:entry-runtime-with-compiler.js

通过名字,我们就可以猜到,完整版比运行时版本多了一个传说中的 compiler,而 compiler 在我们介绍目录结构的时候说过,它的作用是:编译器代码的存放目录,将 template 编译为 render 函数。除了 cjses 版本的输出,对于 umd 模块格式的输出,同样也分为 运行时版完整版,并且还分为 生产环境开发环境

之所以要区分 运行时版完整版,主要是省去了将字符串编译为 render 函数的这个过程,我们可以把这个过程在代码构建的时候去完成,这样真正运行的代码就省去了这一步骤,提升了性能,同时可以将 compiler 单独抽离为一个包,还减小了库的体积。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant