查看原文
其他

中杯超大杯中间的新选择—— Vue2.7 + Vite + TS 实践

前端lucio 前端Q 2022-10-10

点击上方 前端Q,关注公众号

回复加群,加入前端Q技术交流群


前言

选择vue2,是因为我们的网页需要支持IE11

但是同时,我们又非常向往vue3那种组合式API的开发方式。

我们还希望有vite,用于加快服务器启动和打包的速度。

为了进一步写出规范的代码,减少出错的可能,我们再用上TypeScript,TypeScript的使用,除了更好的类型判断,最最重要的,是更好的面向接口编程。

Vue2和Vue3怎么选择?

对于vue2和vue3的选择,主要需要考虑的点还是在vue3的兼容性上。

vue3兼容性的限制取决于浏览器对Proxy对象的支持[1]。而且这个不兼容无法通过babel抹除[2]

babel不支持proxy:

Unsupported feature

Due to the limitations of ES5, Proxies cannot be transpiled or polyfilled. See support in various JavaScript engines[3].

proxy的兼容性:

Proxy object

可以看到,不兼容的浏览器大概占比有3.5%左右。

由此我们的策略是:

  • 可用性要求高的外部的web,用vue2。
  • 其他的,比如工具类、内部的web,大胆用vue3。

vue2使用组合式api的体验如何?

我们的工程一开始就是用vue3写的,技术栈是vue3+vite+ts,用上了组合式api和<script setup>语法糖等新特性。

后面因为兼容性问题改成vue2.6.x,这个修改的过程,需要改的地方,非常少

7月份vue2.7.x也发布release版本,和vue3更加相似,需要改的地方就更少了。

下文实践环节,主要介绍vue2.7的开发流程。

如果对vue2.7+组合式api的开发流程感兴趣,可以参考另一篇文章Vue2+TypeScript+CompositionAPI实践[4]

将会学到什么?

使用如下的技术栈搭建web工程

  • vue2.7
  • vite
  • TypeScript
  • 组合式API+ <script setup>语法糖

开始实践

vue2.7的特性

下面先看看vue2.7向后兼容的特性:

  • `@vue/composition-api`[5] 合并进 Vue 2。这会让使用 Composition API 开发的库同时支持 Vue2 和 Vue3。
  • 单文件组件中的<script setup>语法。
  • 提升的 TypeScript 类型支持。
  • 正式在 Vite 中支持 Vue 2,新增官方的\@vitejs/plugin-vue2插件[6](2.6的支持是通过非官方插件 vite-plugin-vue[7]实现的)

创建vue2.7 的ts项目

vite文档[8]

vite没支持直接创建vue2项目,我们直接用vite创建一个vue3+ts的项目就可以,然后再修改vue的版本为2.7.x。

可以看到.vue文件已经是用上和组合式api<script setup>语法糖,我们不需要再做修改。

需要注意vue对象中没有createApp,如果要用,还是得引入@vue/composition-api

2.6版本:需要引入@vue/composition-api,修改ref@vue/composition-api引入)

<script setup lang="ts">
import { ref } from 'vue'

defineProps<{ msg: string }>()

const count = ref(0)
</script>

<template>
<h1>{{ msg }}</h1>

<div class="card">
<button type="button" @click="count++">count is {{ count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test HMR
</p>
</div>

</template>

<style scoped>
.read-the-docs {
color: #888;
}
</style>
复制代码

vite支持vue2

vite支持vue2需要用到\@vitejs/plugin-vue2插件[9]

//vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue2';

export default defineConfig({
  plugins: [
    vue(),
  ],
}  
复制代码

ESLint和TypeScript配置

eslint-plugin-vue需要升级到9.x版本,同时ts配置文件加上下面的代码,否则<template>标签中的变量会报未定义的错误。

//tsconfig.json
"vueCompilerOptions": {
 "target"2.7
}
复制代码

vue2.7的限制

以下功能已明确不会进行移植:

  • createApp()(Vue 2 没有独立的 app scope)
  • Top-level await in <script setup>(Vue 2 不支持异步组件初始化)
  • 在模板表达式中支持 TypeScript 语法(不兼容 w/ Vue 2 解析器)
  • 响应式转换 Reactivity transform(仍处于实验性阶段)
  • expose 选项不支持 options 组件(但 <script setup> 支持 defineExpose() )

兼容更多的浏览器版本

npm run build查看构建产生的文件,我们可以发现其js文件是作为module模块引入的,这是因为vite默认支持的浏览器基线是支持ESM的现代浏览器。

ESM兼容性[10]

module的兼容性

所以像IE 11这种传统浏览器是不支持的。

兼容传统浏览器

测试兼容性可以用下面这个在线工具:测试浏览器兼容性的在线工具](app.lambdatest.com/console/rea…[11])

为了兼容IE11,我们需要用到`@vitejs/plugin-legacy`[12]这个插件,我们先按官网的方式引入。

// vite.config.ts
import legacy from '@vitejs/plugin-legacy'

export default {
  plugins: [
    legacy({
      targets: ['defaults']
    })
  ]
}
复制代码

兼容停止维护的浏览器

target值的知识,参考`browserslist`[13]

发现在IE 11依旧白屏,我们看看defaults的值是什么:> 0.5%, last 2 versions, Firefox ESR, not dead

IE 11已经停止维护,已经被排除在not dead之外。

稍微修改一下target的值targets: ['> 0.01%, last 10 versions, Firefox ESR']

可以了!

参考文献

Vue 2.7 "Naruto" Released[14]

Vue3[15]

\[RFC\] 关于 Vue 3 的 IE11 支持[16]

关于本文

作者:前端lucio

https://juejin.cn/post/7122750299457978404


往期推荐


两个真实线上故障让你彻底搞懂package.json中的脱字符(^)
API 请求慢?这次锅真不在后端
为什么有人说 vite 快,有人却说 vite 慢?

最后

  • 欢迎加我微信,拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

点个在看支持我吧

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存