fe ? not exsit ?

运行时编译器组合与只包含运行时(vue)

介绍

lifecircle

如vue的生命周期图所示,一个关键不可少的步骤: 编译的过程。用于连接vue初始的options与vdom机制的桥梁, 把options对象里面的数据和vue语法写的模版编译成redner函数。

分析

import

明确版本vue2.5.17-beta.0,platforms/web/entry-runtime-with-compiler.js && platforms/web/entry-runtime.js。 从源码的这两个入口可以得出结论:

Vue提供了 2 个版本,一个是 Runtime + Compiler 的,一个是 Runtime only 的,前者是包含编译代码的,可以把编译过程放在运行时做,后者是不包含编译代码的,需要借助中间件事先把模板编译成 render函数。

在稍微看一下entry-runtime-with-compiler.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function(){
//存在options.render,直接render,也就是mount
if (!options.render) {
var template = options.template;
// 有template,直接作为模版
if (template) {
...
} else if (el) {
// 反之, el作为模版
template = getOuterHTML(el);
}
if (template) {
//如果获取了模版,转化为render
...
}
}
return mount.call(this, el, hydrating)
};

程序优先检查render,找不到就查看是否有tempalte,再其次检查el属性从html文件里读区。
template是html模版,编译以后就成render函数了。代码运行的时候也会先把template编译成render,然后再用来渲染dom。

如若不使用vue-loader或vueify, 需要自己写个jsx的render函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 不需要编译器
new Vue({
//h函数即creatElement返回一个vdom(vnode树
render (h) {
return h('div', 'hello, world');
}
})

// 需要编译器
new Vue({
template: '<div>{{hi}}</div>'
data: () => ({
hi: 'hello, world'
})
})

一般情况下,为了更加优雅便捷通常使用单文件组件模式,使用vue-loader编译成render的形式。总结一下,为了更好的性能,这两种方式最终结果都可以应用vue的runtime版本。webpack应用如下代码

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
...
resolve: {
extensions: ['.js', '.vue'],
alias: {
//以esm加载方式为例
vue: 'vue/dist/vue.runtime.esm.js',
}
}
...
}

如果我的应用是简单应用,根本不希望引入webpack、vue-loader等中间件。那就用entry-runtime-with-compiler入口打包出来的完全体版本了,vue本身就存在一个解析模版引擎。当然性能也会变差,因为这个过程就要在浏览器的解析中运行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// index.html
<div> hello, world</div>

//hello.js
import template from './index.html';
export default({
template
})

// vue import.js
import Hello from 'hello.js';
new Vue({
el: 'test',
template: '<hello></hello>',
components: {
Hello
}
})

//以上是一个在浏览器环境中解析的一个小版本。跑通例子需要webapck babel版本哦。。

利弊

  • 只包含运行时的好处其实也就是编译模版中间件的好处:
    • 如上所示预编译避免了运行时编译的开销。
    • 避免了csp限制
  • 坏处
    • 依赖编译中间件。也就依赖webpack rollup等构建工具。
    • 项目庞大时,由于需要vue-loader编译vue模版,导致编译过程过慢。

参考

[关于csp的知识] http://www.ruanyifeng.com/blog/2016/09/csp.html