0

Code Review for Vue 2.0 Preview

 2 years ago
source link: https://jiongks.name//blog/code-review-for-vue-next/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Code Review for Vue 2.0 Preview

是的!Vue 2.0 发布了! 源代码仓库在此

首先,当我第一次看到 Vue 2.0 的真面目的时候,我的内心是非常激动的

来个简单的 demo,首先把 dist/vue.js 导入到一个空白的网页里,然后写:

当然,在大家阅读下面所有的内容之前,先想象一下,这是一个运行时 min+gzip 后只有 12kb 大小的库

<script src="./dist/vue.js"></script>

<div id="app">
  Hello {{who}}
</div>
<script>
  new Vue({
    el: '#app',
    data: {who: 'Vue'}
  })
</script>

你将看到 “Hello Vue”

然后再看一个神奇的:

<script src="./dist/vue.js"></script>

<div id="app"></div>
<script>
  new Vue({
    el: '#app',
    render: function () {
      with (this) {
        __h__('div',
          {staticAttrs:{"id":"app"}},
          [("\n  Hello "+__toString__(who)+"\n")],
          ''
        )
      }
    }
    data: {who: 'Vue'}
  })
</script>

这个是 compile 过后的格式,大家会发现首先 #app 下不需要写模板了,然后 <script> 里多了一个 render 字段,Vue 在运行时其实是会把模板内容先转换成渲染方法存入 render 字段,然后再执行,如果发现 render 已经存在,就跳过模板解析过程直接渲染。所以在 Vue 2.0 中写一段模板和写一个 render option 是等价的。为什么要这样设计,稍后会我们会涉及到。

Code Review

废话不说,来看仓库

哎呀好东西太多我都不知道该先讲哪个啦!

package.json - -

https://github.com/vuejs/vue/blob/next/package.json

先看这里,我个人习惯是拿到仓库之后除了 README (它没写) 就先看这个。和 1.x 相比,开发工具链还是以 rollup + webpack + karma 为主,开发的时候用 webpack 加 watch;打包的时候用 rollup 快速而且可以自动删掉没用到的代码片段;测试的时候用 karma 各种组合,包括 e2e、spec、coverage、sauce等。语法检查用了 eslint 这个似乎没什么争议和悬念。另外我发现了两个新东西:nightwatchselenium-server

另外你们就选眼睛再迟钝也会看到 ssr 这个词吧!对,就是服务端渲染 Server-Side Rendering!先不急,这个最后说,你们可以先去 high 一会儿

src

作为一个见证了一小段 Vue 2.0 成长过程的脑残粉,我得跟大家从时间线的角度介绍一下这个文件夹:

compiler + runtime

早些时候 Vue 2.0 的代码还是这样分的,一半运行时,一半(预)编译时,中间会通过一个 JavaScript 的格式严格划清界限,即源代码 template + JavaScript 经过编译之后变成了一段纯 JavaScript 代码,然后这段纯 JavaScript 的代码又可以在运行时被执行渲染。

这里面奇妙的地方是:编译时的代码完全可以脱离浏览器预执行,也可以在浏览器里执行。所以你可以把代码提前编译好,减轻运行时的负担。

由于 Vue 2.0 对 template 的解析没有借助 DOM 以及 fragment document,而是在 John Resig 的 HTML Parser 基础上实现的,所以完全可以在任何主流的 JavaScript 环境中执行,这也为 ssr 提供了必要的基础

Vue 最早会打包生成三个文件,一个是 runtime only 的文件 vue.common.js,一个是 compiler only 的文件 compiler.js,一个是 runtime + compiler 的文件 vue.js,它们有三个打包入口,都放在了 entries 目录下,这是 src 里的第三个文件夹,第四个文件夹是 shared,放置一些运行时和编译时都会用到的工具方法集。

compiler + runtime + platforms

Wahahaha~

这要说到 Vue 2.0 的第二个优点:virtual-DOM!virtual-DOM 有很多优点,也被很多人热议,而 Vue 2.0 里面的 virtual-DOM 简直是把它做到了极致!代码非常简练,而且性能超高 (据说秒杀 React,我自己没试过,大家可以自己比比看)。在这一点上编译器的前置起到了非常重要的作用,而且很多 diff 算法的优化点而且是在运行时之前就准备好的。

另外 virtual-DOM 的另一个优点当然就是可以对渲染引擎做一般化的抽象,进而适配到更多类型的终端渲染引擎上!所以在我的怂恿下,小右把本来在 runtime 下的 runtime/dom 文件夹挪到了一个名叫 platforms 的新文件夹下,改名叫 platforms/web/runtime,把本来 compiler 文件夹下 web 相关的 modules 挪到了 platforms/web/compiler

(是的没错,今天在 Weex 的子仓库里已经有另外一个 platforms/weex 文件夹了耶)

compiler + runtime + platforms + server

是的没有错!Vue 2.0 既然已经有了 virtual-DOM,也有了运行环境无关的 compiler,为什么不能 ssr 呢?!Vue 2.0 不只是简单的把预渲染拿到服务端这么简单,Vue 2.0 ssr 除了提供传统的由源文件编译出字符串之外,还提供了输出 stream 的功能,这样服务端的渲染不会因为大量的同步字符串处理而变慢。即:createRenderer() 会返回 renderToString()renderToStream() 两个方法。同时,在 platforms/web 文件夹下除了 runtimecompiler 之外又多了一个 server 目录,这样编译器、服务端流式预渲染、运行时的铁三角架构就这样达成了!

test

说到测试,我惊奇的发现,在带来了这么多颠覆性的改变之后,Vue 2.0 竟然完好保留了绝大多数 1.0 的 API 设计,而且更快更小巧延展性更强。Vue 2.0 在前期研发阶段主要是通过粗线条的 e2e 测试进行质量保障的,因为版本延续性做得非常好,所以这部分在 1.x 的积累已经帮上很大忙了。现在 Vue 2.0 逐渐的在从 feature 的角度在进一步覆盖测试用例,对每个 API 和每个流程进行测试。目前以我个人的感觉主要的常见的链路都已经比较畅通了,具体功能细节上偶尔还是会遇到 bug 待修复,不过作为一个新兴的 Vue 2.0 来说,相信这已经远远超过大家的预期了!

我觉得 Vue 2.0 在编译器和运行时的解耦上做得超级棒!中间格式设计得也非常巧妙,把静态的部分在编译时就分析出来,而且通过非常简单的 __h__, __renderList__ 等方法就搞定了几乎所有的逻辑控制和数据绑定。之前我个人在实践 Weex 的时候也是会把 template 提前 compile,但只是 compile 成一段 JSON,逻辑分析还是在运行时做的,当时和小右交流的时候就在讨论,能不能把分析过程也前置,无奈自己功力不够啊,一直没搞出来。看到 2.0 横空出世,简直是泪流满面有木有!!

还有一件事情也是之前跟小右聊到过,就是目前 Vue 提供的很多 directive 包括 filter 也都是有机会前置处理的,所以在 Vue 2.0 里,有相当一部分 directive 是前置处理成一般格式的,运行时只是针对各端的渲染机制保留了 attr, style, class, event 等几个最基础简单的解析过程,比如 if, for, else 都直接在 compile 的时候被解开了。而且 Vue 2.0 把这部分内容抽象得如此清晰,除了赞叹还是赞叹!!

还有就是,你们去看看 Vue 2.0 的提交记录,300+ 次提交,上万行高效优质的代码,总共花了差不多两周的时间,而且提交时间几乎遍布二十四个小时……

别的不多啰嗦了,我觉得大家还是亲自看过 Vue 2.0 的源码,会对这些内容有更深刻的了解。从今天起,fork + clone Vue 2.0,写写 demo、写写测试、练练英文 XD go!

向本文提出修改或勘误建议

  • tom 2016/04/28 02:04:17

    沙发
  • airyland 2016/04/28 02:12:21

    终于出来了,手动广告,明天立即把vux更新到2.0。
  • Tibbers 2016/05/02 02:29:24

    马上要上项目了,我打算用您的vux,期待升级到vue2.0!
  • 动感小前端 2016/04/28 03:31:42

    好叼的编译提前!没想到竟会越来越快了,要是加上wasm,岂不是赶上native的节奏...
  • leo 2016/04/28 07:15:39

    好鸡冻,最后还是要回去看看编译原理。
  • 题叶 2016/04/28 09:54:19

    所以更加像 React 了...
  • 囧克斯 2016/04/28 10:51:00

    Vue 也有些地方像 angular 像 polymer 我猜大家都能在 Vue 上找到自己喜欢的那部分
  • 说一下Vue.js 2.0 以及自己的一些看法 - 4n70n's Blog - 一生懸命がんばります 2016/04/28 01:05:33

    [...]当然,下面还附了一份Code Review[...]
  • 尤小右 2016/04/28 09:18:39

    不错不错
  • 乐事 2016/04/29 04:40:20

    var vm = new Vue({
    el: 'body',
    data: {who: 'Vue'}
    })

    将el绑定到body上面会出现重复复制body,报错:vue.js:3247Uncaught RangeError: Maximum call stack size exceeded.
    vue.js:3251Uncaught TypeError: Cannot read property 'removeChild' of null。2.0不可以直接绑定body了是吗?
  • 东方孤思子 2016/04/29 06:09:25

    为什么 Weex 不直接叫 Vue-Native 呢?23333
  • Fake 2016/04/30 10:45:18

    说好的code review 呢
  • 前端小菜 2016/05/02 05:36:15

    编译时的代码完全可以脱离浏览器预执行,也可以在浏览器里执行。所以你可以把代码提前编译好,减轻运行时的负担--这句话是什么意思,js还有编译这一说吗?
  • 二锅头 2016/05/08 09:19:29

    想问下nightwatch中有些断言方法我在文档中(包括nodejs的assert文档)没有看到,例如assert.count .value .evaluate方法,这些是从哪来的呢?
  • 二锅头 2016/05/09 10:48:44

    发现好像是自定义的断言
  • Vue 学习笔记 R12; 好JSER 2016/05/14 04:41:11

    [...]Announcing Vue.js 2.0(译)Announcing Vue.js 2.0Code Review for Vue 2.0 PreviewVue 2.0 数据绑定实现一瞥[...]
  • hiyuki 2016/05/17 02:05:24

    请问vue2.0源码用的是那种预编译语言啊?
  • hiyuki 2016/05/17 03:19:08

    哦,里面的类型声明是flow吧
  • HarveyZ 2017/01/15 06:41:05

    刚接触vue2,发现学习起来感觉好有心劲!!!早日用到生产环境!

Related Issues not found

Please contact @jinjiang to initialize the comment


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK