el's blog

A noder, FEer. use express, vue...etc

Vue You are using the runtime-only build
解决 You are using the runtime-only build of Vue where the template compiler is not available

场景

早上起来新建个项目写单测的时候发现报出一个错误

1
2
3
4
console.error node_modules/vue/dist/vue.runtime.common.js:572
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
(found in <Root>)

runtime-only ? 这是什么情况,我只是在单测代码里构建了一个 vm 对象啊,写入了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Vue from 'vue';
let vm = new Vue({
template: `
<p>{{ text }}</p>
`,
data () {
return {
text: 'hello world'
}l
}
}).$mount(null);
// ...

接着是 npm run unit 启动的

1
2
3
"scripts": {
"unit": "jest test/unit/specs --coverage"
}

解决方案

查了查资料得知 vue2 分为完整构建(包含独立构建和运行时构建) 和 运行时构建两种模式。

简单来说, 完整构建和运行时构建的区别就是:可不可以用template选项。运行时构建少了编译 template 为 render 函数的一个阶段所以代码小一些。

上段代码中由于 vm 使用了 template 所以需要完整构建,我找了找 vue 的 npm package 的 main 入口用的是 vue.runtime.common.js,这个是运行时构建,于是乎报错。

只要修改单测代码中的一句话,引用完整构建的 vue 函数就行了

1
2
3
import Vue from 'vue/dist/vue.min.js';
// ...

思考

那么问题来了,我们平常写项目代码的时候是直接使用 import Vue from 'vue' 的,为何不是使用完整构建呢?

那是因为 webpack 中的 vue-loader 已经提前把你的 vue 文件中的 template 给编译成了 render 函数。

附上 vue2 dist目录下的文件

  • vue.common.js 基于 CommonJS 的完整构建
  • vue.esm.js 基于 ES Module 的完整构建
  • vue.js 基于 UMD 的完整构建,可以用 cdn 直接引入
  • vue.min.js 和 vue.js 一样, 属于压缩后版本
  • vue.runtime.common.js 基于 CommonJS 的运行时构建
  • vue.runtime.esm.js 基于 ES Module 的运行时构建
  • vue.runtime.js 基于 UMD 的运行时构建,可以用 cdn 直接引入
  • vue.runtime.min.js 和 vue.runtime.js 一样, 属于压缩后版本

如果想变动使用的 vue 文件,除了在 import 的时候写上具体路径外,还可以使用 webpack 别名

1
2
3
4
5
6
7
{
resolve: {
alias: {
'vue$': 'vue.esm.js'
}
}
}