vue的不同构建版本的解释
前言:最近在做vue2组件库升级到vue3,有些高级组件用到了 组件选项对象 <component :is="{ 组件选项对象 }"></component>
,并且用到vue2的 extend,也支持组件选项对象。使用类似下面
// 创建构造器
var Profile = Vue.extend({ // 组件选项对象
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
问题是:升级到vue3后,发现并不支持了,感觉很难受,因为封装了组件选项的组件特别好用。 后面发现,引入另一个vue的构建版本就可以搞定了!!
解法也很简单,配置一下vue的构建版本即可。目前我用的是vite。用webpack配置文件也是一样的写法
// 找到 vite.config.js 或 webpack。config.js 或 vue.config.js
// 找到 resolve属性, 配置别名
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js' // 增加这一行 , 增加动态编译的能力
}
}
要解释为什么这样就可以,需要理解vue的构建版本,首先需要知道vue的默认构建版本是什么?
vue的构建版本解释
问题:import { createApp } from 'vue'
(vue3的引入), from后面跟的是 vue哪个版本? 如果不用import不用打包,直接在script标签内用呢?vue是引入哪个构建版本?
- 打开vue的源码dist包 或 找vue的CDN,会有多个构建版本。默认是什么?分别是在什么场景下去用?
// 服务端渲染。 通过 `require()` 在 Node.js 服务器端渲染使用。
vue.cjs.js
vue.cjs.prod.js
// 使用构建工具,如 `webpack`,`rollup` 和 `parcel` 等打包出来的工程项目
vue.esm-bundler.js
vue.runtime.esm-bundler.js
// 通过浏览器中的 `<script src="...">` 直接使用,暴露全局Vue
vue.global.js
vue.global.prod.js
vue.runtime.global.js
vue.runtime.global.prod.js
// 在浏览器中通过 `<script type="module">` 来使用(浏览器原生 ES 模块导入使用)
vue.esm-browser.js
vue.esm-browser.prod.js
vue.runtime.esm-browser.js
vue.runtime.esm-browser.prod.js
我们使用vue可能会有4种场景:
- 通过浏览器中的
<script src="...">
直接使用,暴露全局Vue - 在浏览器中通过
<script type="module">
来使用(浏览器原生 ES 模块导入使用)- 使用带
esm-browser
关键字的**.esm-browser.**.js
- 使用带
- 使用构建工具,如
webpack
,rollup
和parcel
等打包出来的工程项目- 使用带
esm-bundler
关键字的**.esm-bundler.**.js
- 解决我上面提的问题,
import { createApp } from 'vue'
(vue3的引入) from后面默认 跟的是 vue哪个版本?- 首先是通过打包工具构建的,所以是 带esm-bundler关键字的
vue.runtime.esm-bundler.js
(默认) 仅运行时,并要求所有模板都要预先编译。这是构建工具的默认入口 (通过package.json
中的 module 字段),因为在使用构建工具时,模板通常是预先编译的 (例如:在*.vue
文件中)。vue.esm-bundler.js
包含运行时编译器。如果你使用了一个构建工具,但仍然想要运行时的模板编译 (例如,DOM 内 模板或通过内联 JavaScript 字符串的模板),请使用这个文件。你需要配置你的构建工具,将 vue 设置为这个文件。
- 使用带
- 服务端渲染。 通过
require()
在 Node.js 服务器端渲染使用。- 使用带
cjs
关键字的**.cjs.**.js
- 使用带
细心的小伙伴应该有疑问, runtime 和 prod 是啥意思? 有什么区别? 比如
vue.esm-browser.js
vue.esm-browser.prod.js
vue.runtime.esm-browser.js
vue.runtime.esm-browser.prod.js
- prod:这个很好理解,就是生产环境使用的压缩版
- runtime:表示 仅运行时(运行时的意思:项目在运行中 使用中)并要求所有模板都要预先编译,无动态编译的能力。 (某些vue的api会用到动态编译的能力)
- 比如文章的开头,Vue.extend需要动态编译的能力,所以需要使用不带runtime关键字的构建版本 以下是vue.extend的用法,感受一下运行时 动态编译
另外 render 方法是底层生成vnode的api,在任何一个vue的构建版本都需要,所以render方法不需要编译器
另外,敲黑板:
```javascript // 如果需要在客户端上编译模板 (即:将字符串传递给 template 选项,或者使用元素的 DOM 内 HTML 作为模板挂载到元素),你将需要编译器,因此需要完整的构建版本:// 创建构造器
var Profile = Vue.extend({ // 组件选项对象
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
// 需要编译器 使用不带runtime关键字的构建版本 Vue.createApp({ template: ‘
{{ hi }}
‘
})
// 不需要 Vue.createApp({ render() { return Vue.h(‘div’, {}, this.hi) } }) ```
- 当使用
vue-loader
时,*.vue
文件中的模板会在构建时预编译为 JavaScript,在最终的捆绑包中并不需要编译器,因此可以只使用运行时构建版本(带runtime的,不做额外配置控制的话,vue脚手架 默认是用这个版本)。- 即使有vue-loader,如果需要 动态编译能力 的话,还是要用不带runtime的版本
码字不易,点赞鼓励!