Skip to content

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

@zhuping

Description

@zhuping

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 单独抽离为一个包,还减小了库的体积。

参考

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions