源码地址:vuejs/vue
1.体验vue 的两种方式
- 工程化项目中,webpack结合 vue-loader 的情况,
- 非工程化项目中HTML 文件中引入 CDN
这两种情况对应了vue的 runtime 与runtimeWithCompiler两个版本
需要发布版本时,需要运行package.json 中的npm run build
"build": "node scripts/build.js"
找到这个文件,这个文件就是打包时候运行的文件,这个文件下的buildEntry方法运行的参数包含了打包时候的配置:
function buildEntry (config) {
....
return rollup.rollup(config)
.......
}
这个config参数在 config.js 文件里
const builds = {
// 完整版本配置
'***-full-***': {
// 入口文件
entry: resolve('web/entry-runtime-with-compiler.js'),
// 输出目录
dest: resolve('dist/***.js')
},
// 运行时版本配置
'****-runtime-****': {
// 入口文件
entry: resolve('web/entry-runtime.js'),
// 输出目录
dest: resolve('dist/***.runtime.js'),
}
}
// 模块向外暴露的接口
exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
分别打开这两个文件:
- entry-runtime.js
/* @flow */
import Vue from './runtime/index'
export default Vue
- entry-runtime-with-compiler.js
....
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (el) {
......
if (template) {
// 开始时做标记
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
mark('compile')
}
// 先编译模板
const { render, staticRenderFns } = compileToFunctions(template, {
outputSourceRange: process.env.NODE_ENV !== 'production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
// 挂在渲染函数
options.render = render
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
mark('compile end')
// 找出编译时间差
measure(`vue ${this._name} compile`, 'compile', 'compile end')
}
}
return mount.call(this, el, hydrating)
}
2.对比两个版本的差异
- runtime 版本只向外暴露出一个 Vue 类供我们使用
- 完全版的不仅暴露出了 vue 类,而且还重写了$mounted 方法,并且做了performance的测算。
- 更重要的是,增添了模板的编译
- 其实在工程化项目中,也有编辑过程,只不过是通过 vue-loader 等一些预加载插件进行了预编译