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.jsvue.cjs.prod.js// 使用构建工具,如 `webpack`,`rollup` 和 `parcel` 等打包出来的工程项目vue.esm-bundler.jsvue.runtime.esm-bundler.js// 通过浏览器中的 `<script src="...">` 直接使用,暴露全局Vuevue.global.jsvue.global.prod.jsvue.runtime.global.jsvue.runtime.global.prod.js// 在浏览器中通过 `<script type="module">` 来使用(浏览器原生 ES 模块导入使用)vue.esm-browser.jsvue.esm-browser.prod.jsvue.runtime.esm-browser.jsvue.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.jsvue.esm-browser.prod.jsvue.runtime.esm-browser.jsvue.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的版本
码字不易,点赞鼓励!
