问题描述
今天有童鞋在用 vue 项目写代码的时候,问我为啥会出现以下报错?
[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>)
问这个问题的童鞋估计是没怎么看过 vue 的源码,vue 官网是没有这一部分的介绍的,得自己看源码!
问题原因
由于项目中引用的是 vue.runtime.esm.js
,然后在代码中又用了 template
属性,导致无法解析 template
里面内容,项目报错。
解决方案
针对不同脚手架可以这样做:
vue-cli 脚手架创建的项目
创建或修改 vue.config.js
文件,修改 webpack
配置,把项目中的 vue 换成 “编译 + 运行” 版本。
module.exports = {
...
chainWebpack: config => {
config.resolve.alias
.set("vue$",'vue/dist/vue.esm.js');
...
}
};
普通 Webpack 项目
修改一下 webpack
配置,把项目中的 vue 换成 “编译 + 运行” 版本。
module.exports = {
// ...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
Rollup 项目
修改Rollup
配置,把项目中的 vue 换成 “编译 + 运行” 版本。
const alias = require('rollup-plugin-alias')
rollup({
// ...
plugins: [
alias({
'vue': 'vue/dist/vue.esm.js'
})
]
})
浏览器
直接 CDN
引用 UMD
类型的 “编译 + 运行” 版本。
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
ok!下面我们结合 Demo 分析一下 vue 的各个 dist(资源包)之间的区别。
开始
为了更好的去分析 vue 各个资源包之间的区别,我们简单的搭建一个 vue 项目。
首先创建一个目录叫 vue-dist-demo
,然后初始化 npm
:
mkdir vue-dist-demo && cd vue-dist-demo && npm init
接下来我们需要安装 webpack 相关的依赖:
安装 webpack
webpack 核心库。
在工程目录 vue-dist-demo
执行以下命令安装 webpack:
npm install -D webpack --registry https://registry.npm.taobao.org
安装 webpack-cli
webpack 指令库。
在工程目录 vue-dist-demo
执行以下命令:
npm install -D webpack-cli --registry https://registry.npm.taobao.org
安装 webpack-dev-server
webpack 开发者服务框架。
在工程目录 vue-dist-demo
执行以下命令:
npm install -D webpack-dev-server --registry https://registry.npm.taobao.org
安装 webpack-chain
webpack 配置工具。
在工程目录 vue-dist-demo
执行以下命令:
npm install -D webpack-chain --registry https://registry.npm.taobao.org
创建 webpack 配置
在工程目录 vue-dist-demo
下创建一个 webpack.config.js
文件:
touch webpack.config.js
然后对 webpack.config.js
进行配置,用 webpack-chain
导入一个 webpack 配置:
const config = new (require('webpack-chain'))();
module.exports = config.toConfig();
为了开发方便,我们在 package.json
中声明两个脚本 build
跟 dev
:
{
"name": "vue-dist-demo",
"version": "1.0.0",
"description": "## 问题描述",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf dist && webpack --mode=production",
"dev": "webpack-dev-server --mode=development --progress"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.4.0",
"webpack-dev-server": "^3.11.0",
"webpack-chain": "^6.5.1",
"webpack-cli": "^3.3.12"
}
}
入口与出口
我们首先在工程目录 vue-dist-demo
下创建一个 src
目录,然后在 src
目录下创建一个 main.s
文件:
mkdir src && cd src && touch main.js && cd ..
然后我们找到 webpack.config.js
文件,对 webpack 的入口和出口进行配置:
const path = require('path');
const config = new (require('webpack-chain'))();
config
.context(path.resolve(__dirname, '.')) // webpack 上下文目录为项目根目录
.entry('app') // 入口文件名称为 app
.add('./src/main.js') // 入口文件为 ./src/main.ts
.end()
.output
.path(path.join(__dirname, './dist')) // webpack 输出的目录为根目录的 dist 目录
.filename('[name].[hash:8].js') // 打包出来的 bundle 名称为 "[name].[hash:8].js"
.publicPath('/') // publicpath 配置为 "/"
.end()
安装 vue
vue 核心 API。
npm install vue --registry https://registry.npm.taobao.org
安装 vue-loader
.vue
文件加载器。
npm install vue-loader -D --registry https://registry.npm.taobao.org
安装 vue-template-compiler
.vue
文件模版解析器。
npm install vue-template-compiler -D --registry https://registry.npm.taobao.org
安装 html-webpack-plugin
npm install -D html-webpack-plugin -D --registry https://registry.npm.taobao.org
接下来我们在工程目录 sy_webpack-wedding
底下创建一个 public
目录,然后在 public
目录下创建一个 index.html
文件作为我们 app 的入口页面:
mkdir public && touch public/index.html
然后将以下内容写入 public/index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<noscript>your browser should support javascript!</noscript>
<div id="app"></div>
<!-- html-webpack-plugin 将自动引入入口文件 -->
</body>
</html>
webpack 配置全部内容:
const path = require('path');
const config = new (require('webpack-chain'))();
config
.context(path.resolve(__dirname, '.')) // webpack 上下文目录为项目根目录
.entry('app') <