中杯超大杯中间的新选择——vue2.7+vite+ts实践

6,120

前言

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

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

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

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

Vue2和Vue3怎么选择?

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

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

babel不支持proxy:

Unsupported feature

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

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实践

将会学到什么?

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

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

开始实践

vue2.7的特性

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

创建vue2.7 的ts项目

vite文档

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插件

//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兼容性

module的兼容性

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

兼容传统浏览器

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

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

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

export default {
  plugins: [
    legacy({
      targets: ['defaults']
    })
  ]
}

兼容停止维护的浏览器

target值的知识,参考browserslist

发现在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

Vue3

[RFC] 关于 Vue 3 的 IE11 支持