目录
总结:始终推荐大家使用运行时版本 vue.runtime.xxx.js
Vue的不同构建版本
也就是打包之后产生的不同版本的vue.js
- npm run build重新打包所有文件
- 官方文档-对不同构建版本的解释:dist/README.md
https://github.com/denghuiquan/vue/tree/2.6/dist
Explanation of Build Files
UMD | CommonJS | ES Module | |
---|---|---|---|
Full | vue.js | vue.common.js | vue.esm.js |
Runtime-only | vue.runtime.js | vue.runtime.common.js | vue.runtime.esm.js |
Full (production) | vue.min.js | ||
Runtime-only (production) | vue.runtime.min.js |
Terms 术语
Full 完整版: builds that contain both the compiler and the runtime. 同时包含编译器和运行时的版本。
Compiler 编译器: code that is responsible for compiling template strings into JavaScript render functions. 用来将模版字符串转换为JavaScript渲染函数的代码,体积大,效率低。
Runtime 运行时: code that is responsible for creating Vue instances, rendering and patching virtual DOM, etc. Basically everything minus the compiler. 用来创建Vue实例,渲染并处理虚拟DOM等的代码,体积小,效率高,基本上就是除去了编译器的代码。
UMD: UMD builds can be used directly in the browser via a
<script>
tag. The default file from Unpkg CDN at https://unpkg.com/vue is the Runtime + Compiler UMD build (vue.js
). UMD版本通用的模块版本,支持多种模块方式,vue.js默认文件就是运行时+编译器的UMD版本。CommonJS: CommonJS builds are intended for use with older bundlers like browserify or webpack 1. The default file for these bundlers (
pkg.main
) is the Runtime only CommonJS build (vue.runtime.common.js
). CommonJS用来配合老的打包工具,如Browserify或webpack 1。ES Module: ES module builds are intended for use with modern bundlers like webpack 2 or rollup. The default file for these bundlers (
pkg.module
) is the Runtime only ES Module build (vue.runtime.esm.js
). 从vue2.6版本开始Vue会提供两个ES Modules(ESM)构建文件,为现代化打包工具提供的打包版本。ESM格式被设计为可以被静态分析,所以打包工具可以利用这一点来进行代码树抖摇“tree-shaking”,将并用不到的代码排除出最终的包。(未来的趋势)
1、
ES6 Module
和CommonJS
模块的区别:CommonJS
是对模块的浅拷贝,ES6 Module
是对模块的引用,即ES6 Module
只存只读,不能改变其值,具体点就是指针指向不能变,类似const
import
的接口是read-only
(只读状态),不能修改其变量值。 即不能修改其变量的指针指向,但可以改变变量内部指针指向,可以对commonJS
对重新赋值(改变指针指向),但是对ES6 Module
赋值会编译报错。
2、
ES6 Module
和CommonJS
模块的共同点:CommonJS
和ES6 Module
都可以对引入的对象进行赋值,即对对象内部属性的值进行改变。
**运行时版本与含编译器版本的区别**
准备工作
预先在examples目录下创建一个基本的Hello World的Vue示例,我们取名为01-runtime+compiler。
这个示例非常简单的,仅包含了一个index.html文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">Hello World</div>
<script src="../../dist/vue.js"></script>
<script>
// compiler 编译器,其目的是:把template模版字符串 转换成 render函数
const vm = new Vue({
el: '#app',
template: '<h1>{{msg}}</h1>',
data() {
return {
msg: 'Welcome to Vue World'
}
},
})
</script>
</body>
</html>
这时候可以看到,我们在文件中通过script标签导入的是dist目录下的vue.js,就是运行时+编译器的UMD完整版本,其使用的模块化方式是UMD,支持在浏览器上直接使用,是包含了compiler编译器代码的,其中的编译器compiler部分代码就有三千多行。
从示例代码中,我们可以观察到,代码中我们创建了一个Vue实例vm,并且传入了一个template属性成员,也就是我们说的模版字符串。
上面示例代码我们在浏览器的运行结果如下:
可以看到,页面上显示的结果是我们在构建Vue示例时传入的data的msg内容,已经替换掉了原本hard code在div#app中的Hello World。
打开开发者工具工具观察其渲染的DOM结构,如下:
可以看到,原先写在html内的div#app被我们的vue实例的template中的h1标签给替换了。
接下来我们修改html中引入的vue的文件的版本为:运行时版本的UMD版本,即:vue.runtime.js。再运行查看我们修改后的运行结果:
可以看到此时页面上什么的都输出,而console控制台出现了一个错误提示,如下:
[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 build),运行时版本中的不包含编译器的,这时候编译器不可用。有两种解决方案:1)通过预编译(pre-compile)把我们的templates模版转换成render函数;2)或者使用包含编译器的版本(compiler-included build),也就是说我们的模版是需要完整版才能运行的。
方案2)我们前边已经演示了,是可以正常工作的。这时候我们任然想要使用我们的运行时版本,所以我们template属性成员注释掉,改之使用render函数,修改后的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">Hello World</div>
<script src="../../dist/vue.runtime.js"></script>
<script>
// compiler 编译器,其目的是:把template模版字符串 转换成 render函数
const vm = new Vue({
el: '#app',
// template: '<h1>{{msg}}</h1>', // 需要在compiler-included build,即含编译器的完整版本下才能正常工作
render(h) { // 可以在runtime-only build,即运行时版本中正常工作
// render函数中的参数h, h是一个函数,它是虚拟DOM中用来创建虚拟DOM的。
// render函数中需要把创建出来的虚拟DOM返回出去,才能被正常挂载并渲染到页面上
return h('h1', this.msg)
},
data() {
return {
msg: 'Welcome to Vue World'
}
}
})
</script>
</body>
</html>
此时再来刷新我们的的浏览器查看页面的结果,如下:
可以看到,运行结果跟我们原来在完整版中使用template的结果是一样的。
总结:
- 1、完整版包含编译器,compiler-included build,而编译器部分的代码三千多行;
- 2、运行时版不包含编译器,runtime-only build,所以体积会更小;
- 3、运行时版本的执行效率要比完整版本的执行效率要更高一些。
- 4、基于vue cli创建的项目默认使用的是运行时版本,配合大打包工具中使用的compiler,在编译阶段就已经可以把我们的.vue文件转换为render函数。
为了验证上面?的第4点的说法,我们打开一个基于vue cli创建的的项目来参看一下。
可以看到我们在src/main.js中使用import 导入了 vue,为了查看导入的vue到底是众多vue构建版本中的哪一个,我们需要打开这个项目下的webpack文件,但是vue cli对webpack做了一个深度的封装,所以我们在项目源代码中是看不到webpack的配置文件的。但是它也为我们提供了一个查看项目webpack配置的命令行工具: vue inspect 。 可以看到,使用vue inspect 输出的结果非常的长,不便于查看,我们可以简单使用: vue inspect | grep vue, 大概可以观察出来应该是为vue的引用文件设置了别名alias: vue$, 也就是在项目中使用 import Vue from 'vue' 就是相当于 import Vue from 'vue/dist/vue.runtime.esm.js' 。就是说默认import vue模块的时候,使用的就是vue的运行时版本的esm版本,使用esm模块因为项目使用webpack打包工具,可以方便的实现代码的类型静态分析,以达到实现代码tree-shaking的目的。
当然这里为了更好的查看webpack的配置是否如我们所想,我们还是老老实实版 vue inspect命令行运行的结果内容输出到我们的物理文件中进行查看。这时我们可以使用命令:vue inspect > vue-inspect-output.js 。
$ vue inspect > vue-inspect-output.js
这是我们就得到了一个名为‘vue-inspect-output.js’的使用vue inspect命令得到的当前项目的webpack相关配置信息的文件,内容如下:
{
mode: 'development',
context: '/my-module/imp-vuerouter-usage',
devtool: 'cheap-module-eval-source-map',
node: {
setImmediate: false,
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
output: {
path: '/my-module/imp-vuerouter-usage/dist',
filename: '[name].js',
publicPath: '/',
globalObject: '(typeof self !== \'undefined\' ? self : this)'
},
resolve: {
alias: {
'@': '/my-module/imp-vuerouter-usage/src',
vue$: 'vue/dist/vue.runtime.esm.js'
},
extensions: [
'.mjs',
'.js',
'.jsx',
'.vue',
'.json',
'.wasm'
],
modules: [
'node_modules',
'/my-module/imp-vuerouter-usage/node_modules',
'/my-module/imp-vuerouter-usage/node_modules/@vue/cli-service/node_modules'
]
},
resolveLoader: {
modules: [
'/my-module/imp-vuerouter-usage/node_modules/@vue/cli-plugin-eslint/node_modules',
'/my-module/imp-vuerouter-usage/node_modules/@vue/cli-plugin-babel/node_modules',
'node_modules',
'/my-module/imp-vuerouter-usage/node_modules',
'/my-module/imp-vuerouter-usage/node_modules/@vue/cli-service/node_modules'
]
},
module: {
noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/,
rules: [
/* config.module.rule('vue') */
{
test: /\.vue$/,
use: [
/* config.module.rule('vue').use('cache-loader') */
{
loader: 'cache-loader',
options: {
cacheDirectory: '/my-module/imp-vuerouter-usage/node_modules/.cache/vue-loader',
cacheIdentifier: '88440162'
}
},
/* config.module.rule('vue').use('vue-loader') */
{
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false
},
cacheDirectory: '/my-module/imp-vuerouter-usage/node_modules/.cache/vue-loader',
cacheIdentifier: '88440162'
}
}
]
},
/* config.module.rule('images') */
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
use: [
/* config.module.rule('images').use('url-loader') */
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
}
}
]
},
/* config.module.rule('svg') */
{
test: /\.(svg)(\?.*)?$/,
use: [
/* config.module.rule('svg').use('file-loader') */
{
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
]
},
/* config.module.rule('media') */
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
use: [
/* config.module.rule('media').use('url-loader') */
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'media/[name].[hash:8].[ext]'
}
}
}
}
]
},
/* config.module.rule('fonts') */
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
use: [
/* config.module.rule('fonts').use('url-loader') */
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:8].[ext]'
}
}
}
}
]
},
/* config.module.rule('pug') */
{
test: /\.pug$/,
oneOf: [
/* config.module.rule('pug').oneOf('pug-vue') */
{
resourceQuery: /vue/,
use: [
/* config.module.rule('pug').oneOf('pug-vue').use('pug-plain-loader') */
{
loader: 'pug-plain-loader'
}
]
},
/* config.module.rule('pug').oneOf('pug-template') */
{
use: [
/* config.module.rule('pug').oneOf('pug-template').use('raw') */
{
loader: 'raw-loader'
},
/* config.module.rule('pug').oneOf('pug-template').use('pug-plain') */
{
loader: 'pug-plain-loader'
}
]
}
]
},
/* config.module.rule('css') */
{
test: /\.css$/,
oneOf: [
/* config.module.rule('css').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
/* config.module.rule('css').oneOf('vue-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('css').oneOf('vue-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('css').oneOf('vue-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('css').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
/* config.module.rule('css').oneOf('vue').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('css').oneOf('vue').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('css').oneOf('vue').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('css').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
/* config.module.rule('css').oneOf('normal-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('css').oneOf('normal-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('css').oneOf('normal-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('css').oneOf('normal') */
{
use: [
/* config.module.rule('css').oneOf('normal').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('css').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('css').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
}
]
},
/* config.module.rule('postcss') */
{
test: /\.p(ost)?css$/,
oneOf: [
/* config.module.rule('postcss').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
/* config.module.rule('postcss').oneOf('vue-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('postcss').oneOf('vue-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('postcss').oneOf('vue-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('postcss').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
/* config.module.rule('postcss').oneOf('vue').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('postcss').oneOf('vue').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('postcss').oneOf('vue').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('postcss').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
/* config.module.rule('postcss').oneOf('normal-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('postcss').oneOf('normal-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('postcss').oneOf('normal-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('postcss').oneOf('normal') */
{
use: [
/* config.module.rule('postcss').oneOf('normal').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('postcss').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('postcss').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
}
]
},
/* config.module.rule('scss') */
{
test: /\.scss$/,
oneOf: [
/* config.module.rule('scss').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
/* config.module.rule('scss').oneOf('vue-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('scss').oneOf('vue-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('scss').oneOf('vue-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('scss').oneOf('vue-modules').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('scss').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
/* config.module.rule('scss').oneOf('vue').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('scss').oneOf('vue').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('scss').oneOf('vue').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('scss').oneOf('vue').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('scss').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
/* config.module.rule('scss').oneOf('normal-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('scss').oneOf('normal-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('scss').oneOf('normal-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('scss').oneOf('normal-modules').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('scss').oneOf('normal') */
{
use: [
/* config.module.rule('scss').oneOf('normal').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('scss').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('scss').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('scss').oneOf('normal').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false
}
}
]
}
]
},
/* config.module.rule('sass') */
{
test: /\.sass$/,
oneOf: [
/* config.module.rule('sass').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
/* config.module.rule('sass').oneOf('vue-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('sass').oneOf('vue-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('sass').oneOf('vue-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('sass').oneOf('vue-modules').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
},
/* config.module.rule('sass').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
/* config.module.rule('sass').oneOf('vue').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('sass').oneOf('vue').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('sass').oneOf('vue').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('sass').oneOf('vue').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
},
/* config.module.rule('sass').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
/* config.module.rule('sass').oneOf('normal-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('sass').oneOf('normal-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('sass').oneOf('normal-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('sass').oneOf('normal-modules').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
},
/* config.module.rule('sass').oneOf('normal') */
{
use: [
/* config.module.rule('sass').oneOf('normal').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('sass').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('sass').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('sass').oneOf('normal').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false,
sassOptions: {
indentedSyntax: true
}
}
}
]
}
]
},
/* config.module.rule('less') */
{
test: /\.less$/,
oneOf: [
/* config.module.rule('less').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
/* config.module.rule('less').oneOf('vue-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('less').oneOf('vue-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('less').oneOf('vue-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('less').oneOf('vue-modules').use('less-loader') */
{
loader: 'less-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('less').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
/* config.module.rule('less').oneOf('vue').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('less').oneOf('vue').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('less').oneOf('vue').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('less').oneOf('vue').use('less-loader') */
{
loader: 'less-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('less').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
/* config.module.rule('less').oneOf('normal-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('less').oneOf('normal-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('less').oneOf('normal-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('less').oneOf('normal-modules').use('less-loader') */
{
loader: 'less-loader',
options: {
sourceMap: false
}
}
]
},
/* config.module.rule('less').oneOf('normal') */
{
use: [
/* config.module.rule('less').oneOf('normal').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('less').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('less').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('less').oneOf('normal').use('less-loader') */
{
loader: 'less-loader',
options: {
sourceMap: false
}
}
]
}
]
},
/* config.module.rule('stylus') */
{
test: /\.styl(us)?$/,
oneOf: [
/* config.module.rule('stylus').oneOf('vue-modules') */
{
resourceQuery: /module/,
use: [
/* config.module.rule('stylus').oneOf('vue-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('stylus').oneOf('vue-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('stylus').oneOf('vue-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('stylus').oneOf('vue-modules').use('stylus-loader') */
{
loader: 'stylus-loader',
options: {
sourceMap: false,
preferPathResolver: 'webpack'
}
}
]
},
/* config.module.rule('stylus').oneOf('vue') */
{
resourceQuery: /\?vue/,
use: [
/* config.module.rule('stylus').oneOf('vue').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('stylus').oneOf('vue').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('stylus').oneOf('vue').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('stylus').oneOf('vue').use('stylus-loader') */
{
loader: 'stylus-loader',
options: {
sourceMap: false,
preferPathResolver: 'webpack'
}
}
]
},
/* config.module.rule('stylus').oneOf('normal-modules') */
{
test: /\.module\.\w+$/,
use: [
/* config.module.rule('stylus').oneOf('normal-modules').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('stylus').oneOf('normal-modules').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2,
modules: true,
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
/* config.module.rule('stylus').oneOf('normal-modules').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('stylus').oneOf('normal-modules').use('stylus-loader') */
{
loader: 'stylus-loader',
options: {
sourceMap: false,
preferPathResolver: 'webpack'
}
}
]
},
/* config.module.rule('stylus').oneOf('normal') */
{
use: [
/* config.module.rule('stylus').oneOf('normal').use('vue-style-loader') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('stylus').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('stylus').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('stylus').oneOf('normal').use('stylus-loader') */
{
loader: 'stylus-loader',
options: {
sourceMap: false,
preferPathResolver: 'webpack'
}
}
]
}
]
},
/* config.module.rule('js') */
{
test: /\.m?jsx?$/,
exclude: [
function () { /* omitted long function */ }
],
use: [
/* config.module.rule('js').use('cache-loader') */
{
loader: 'cache-loader',
options: {
cacheDirectory: '/my-module/imp-vuerouter-usage/node_modules/.cache/babel-loader',
cacheIdentifier: '6835009f'
}
},
/* config.module.rule('js').use('babel-loader') */
{
loader: 'babel-loader'
}
]
},
/* config.module.rule('eslint') */
{
enforce: 'pre',
test: /\.(vue|(j|t)sx?)$/,
exclude: [
/node_modules/,
'/my-module/imp-vuerouter-usage/node_modules/@vue/cli-service/lib'
],
use: [
/* config.module.rule('eslint').use('eslint-loader') */
{
loader: 'eslint-loader',
options: {
extensions: [
'.js',
'.jsx',
'.vue'
],
cache: true,
cacheIdentifier: '31194c1c',
emitWarning: true,
emitError: false,
eslintPath: '/my-module/imp-vuerouter-usage/node_modules/eslint',
formatter: function () { /* omitted long function */ }
}
}
]
}
]
},
plugins: [
/* config.plugin('vue-loader') */
new VueLoaderPlugin(),
/* config.plugin('define') */
new DefinePlugin(
{
'process.env': {
NODE_ENV: '"development"',
BASE_URL: '"/"'
}
}
),
/* config.plugin('case-sensitive-paths') */
new CaseSensitivePathsPlugin(),
/* config.plugin('friendly-errors') */
new FriendlyErrorsWebpackPlugin(
{
additionalTransformers: [
function () { /* omitted long function */ }
],
additionalFormatters: [
function () { /* omitted long function */ }
]
}
),
/* config.plugin('hmr') */
new HotModuleReplacementPlugin(),
/* config.plugin('progress') */
new ProgressPlugin(),
/* config.plugin('html') */
new HtmlWebpackPlugin(
{
templateParameters: function () { /* omitted long function */ },
template: '/my-module/imp-vuerouter-usage/public/index.html'
}
),
/* config.plugin('preload') */
new PreloadPlugin(
{
rel: 'preload',
include: 'initial',
fileBlacklist: [
/\.map$/,
/hot-update\.js$/
]
}
),
/* config.plugin('prefetch') */
new PreloadPlugin(
{
rel: 'prefetch',
include: 'asyncChunks'
}
),
/* config.plugin('copy') */
new CopyWebpackPlugin(
[
{
from: '/my-module/imp-vuerouter-usage/public',
to: '/my-module/imp-vuerouter-usage/dist',
toType: 'dir',
ignore: [
'.DS_Store',
{
glob: 'index.html',
matchBase: false
}
]
}
]
)
],
entry: {
app: [
'./src/main.js'
]
}
}
从输出的文件中我们看到,确实如我们所想的那样,vue cli创建的项目中的webpack配置时为vue的import资源设置类alias别名,如下:
注意别名后的$符号是webpack的语法,表示精准匹配的意思。
所以,使用vue cli创建的的项目默认使用的是vue的运行时版本并且是esm模块方式的版本。
最后再看一下vue cli创建的文件中的App.vue,它是一个单文件组件,我们平时开发项目中经常会创建的.vue后缀的文件就属于这种单文件组件。这些单文件组件浏览器是不支持的。所以我们在打包的时候会将这些单文件组件转换成JavaScript对象,在转换为JavaScript对象的过程中,还会帮我们把这些template模版转换成render函数,所以我们单文件组件在运行的时候也是不需要编译器的。
全文终。 全文的重点在于理解编译器和运行时的区别。
待续ing······