由于 vite 在开发态是基于 ESM 进行模块化开发, 而 ESM 的浏览器兼容版本有限,如下图。
esm-兼容所以,如果你打算使用 vite 作为构建工具去开发,你至少要有一个合适版本的浏览器。如果你和我一样,Chrome
版本的浏览器比较低,但是又不想升级,想留着偶尔方便自测和定位浏览器兼容问题,那我推荐你安装一个Chromium
。这样你就可以一个电脑里面拥有两个 Chrome
。_没有两个chrome的前端不是好前端[狗头]。_
这时候,你可能又会有另外一个问题,_什么是 ESM?_ 关于这个问题,这里不展开说,有兴趣的可以看看这篇文章[1]。通俗易懂的理解,就是在开发态,我们加载的是模块化的 ts
或者 js
,而且在打包后,我们加载的就是的 CommonJS
,如下图。
除此之外,你要升级你的 node
环境到 node 14
以上版本。而如果你也是用的 windows 7
, 这就有了第二个问题, 如何在 windows 7
下安装 node 14
? 需要将下载的 node
包放在指定的 nvm
文件夹同时将系统变量 NODE_SKIP_PLATFORM_CHECK
设置为 1
。
组件准备:因为希望组件风格和之前保持一致,为了更加灵活的修改组件,我们基于antdv[2]进行了简单封装,并发布到私有的 npm
仓库。
组件自动引入unplugin-vue-components
上面的封装也带来另外一个坑,就是会导致无法使用 unplugin-vue-components
。我去提了issues 希望可以支持组件名动态设置[3] 和 PR[4], 应该下个版本 AntDesignVueResolver
就可以支持了。
在实际开发过程中,从 vue2
升级到 vue3
我觉得有几个地方或许是需要适用一下的,这里也提一下。
组合式 API 是一系列 API 的集合, 它是 Vue 3 和 Vue2.7 的内置功能,而对于更老的 Vue 2 版本,则可以使用 @vue/composition-api
包。组合式 API 包括:
是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。个人感觉,不用这个语法糖写法上和
Vue 2
更加接近,而使用这个语法糖写起来则更丝滑些,写法对比如下图:
有两种实现方式,如下图。我个人用下来,觉得写法一
更丝滑些。
你可能也注意到,对整个数组的变更,我用的是 Object.assign
去实现的,因为只有这样,才能保持数据的响应式。这和 Vue 2
也是有区别的,官网也有做说明响应式代理 vs. 原始值[5],原因和 Vue 3
的数据响应式原理有关。至于Vue 3
的数据响应式原理这里不展开说,可以参考我之前写的另一篇文章关于vue3的Proxy[6]。
父组件
打开弹窗
复制代码
子组件
modal
复制代码
setEchartRef(el, index)" class="chart">
empty-box
复制代码
混用 require
和 import
如果项目中存在混用 commonJS 和 ES6 模块的情况,需要使用 @originjs/vite-plugin-commonjs
这个插件的 transformMixedEsModules
配置进行 hotfix。不然会报错Uncaught ReferenceError: require is not defined
。_不过,尽量不要混用,因为尤大大说了这么干不好....Vite will likely never support such dependencies.[7]_
import { defineConfig } from 'vite'
import { viteCommonjs } from '@originjs/vite-plugin-commonjs';
export default defineConfig({
// ...
plugins: [
viteCommonjs({
transformMixedEsModules: true,
}),
]
})
复制代码
个人理解,这个配置类似于 babel
的 sourceType[8]配置项。因为之前在babel
也踩过类似的坑,这里贴出对应 issues4039[9]。其实简单概括就是出现了import和module.exports的混用。
所以,原来项目中用 h
函数渲染图片的写法也要改为es引入,如下:
import exampleImg from './assets/example.png'
import { h } from 'vue';
function renderModal() {
Modal.confirm({
title: '操作确认',
icon: null,
content: () =>
h('div', { style: 'text-align: center;padding-bottom: 32px;' }, [
// 原来vue2的写法 h('img', {attrs: {src: require('./assets/example.png')}})
h('img', { src: exampleImg })]),
});
}
复制代码
关于浏览器兼容问题
vite
的 build.target[10] 配置项可以配置希望兼容的浏览器版本或者 ES 版本,cssTarget[11]可以对 CSS 的压缩设置一个target
,该配置应针对非主流浏览器使用。例如,安卓微信中的 webview,并不支持 CSS 中的十六进制颜色符号, 此时将 build.cssTarget
设置为 chrome61
,可以防止 vite
将 rgba()
颜色转化为 #RGBA
十六进制符号的形式。
除此之外, 还可以使用插件 @vitejs/plugin-legacy
进行更多的浏览器兼容问题处理。例如,在内核 chrome 69
版本的360浏览器中,遇到过Uncaught ReferenceError: globalThis is not defined
这样的报错。网上搜到可以通过解决浏览器端 globalThis is not defined 报错[12]简单快速的 hotfix
可以解决这个问题,但是我始终觉得不够优雅。
后来翻了下文档,实际可以通过 @vitejs/plugin-legacy
的modernPolyfills
配置去解决这个问题,解决配置如下代码。同理,你也可以 Polyfills
你需要的es[13]。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import legacy from '@vitejs/plugin-legacy'
export default defineConfig({
server: {
port: 8080
},
build: {
target: 'es2015', // js兼容处理
cssTarget: 'chrome49', // css兼容处理
}
plugins: [
vue(),
legacy({
targets: ['chrome 49'],
modernPolyfills: ['es.global-this'], // 解决浏览器端 globalThis is not defined 报错
}),
]
})
复制代码
说完这么多坑,最后附上一张比较有意思的图2021年前端框架开发:满意度-感兴趣程度-使用度-熟知度[14]:
有意思的图踩了这么多坑,你可能会问,后悔在新项目里面用 vue3
了吗?我的答案是没有。对于一个不太重的新项目,你又想尝试卷卷 vue3,我个人觉得或许是个不错的选择。
关于本文
https://juejin.cn/post/7137967499202527239
欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,「在看」是最大的支持
》》面试官也在看的算法资料《《
“在看和转发”就是最大的支持