【2021-08-05】Vue 2.x TS 项目升级支持 Vue 3.0 项目改造记录

3,124 阅读7分钟

勿喷,毫无深度内容,这是一个记录过程,是持续更新的,会不断记录新的问题和如何解决。
目前学习小组的学习项目能够支持 2.x3.0 风格在项目中共存,但是不能同时存在于同一个组件内。
主要是考虑了能够让小组里的小伙伴们能够逐渐熟悉过度,而不是硬上 Vue 3.0

补充更新 | 错误记录 | 更新时间:2020-09-21 16:56

目前项目的环境如下,在使用更新检查的时候需要更新的版本

Global 环境

Minor Update New backwards-compatible features.
(*) @vue/cli  4.4.6  ❯  4.5.6  https://github.com/vuejs/vue-cli#readme

Dev 环境

Patch Update Backwards-compatible bug fixes.
(*) vue                           2.6.11  ❯  2.6.12  https://github.com/vuejs/vue#readme
(*) vue-class-component           7.2.3   ❯  7.2.5   https://github.com/vuejs/vue-class-component#readme
(*) @types/chai devDep            4.2.11  ❯  4.2.12  https://github.com/DefinitelyTyped/DefinitelyTyped
(*) vue-template-compiler devDep  2.6.11  ❯  2.6.12  https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#readme

Minor Update New backwards-compatible features.
(*) vue-router                             3.1.6   ❯  3.4.3   https://github.com/vuejs/vue-router#readme
(*) vuex                                   3.4.0   ❯  3.5.1   https://github.com/vuejs/vuex#readme
(*) @vue/cli-plugin-babel devDep           4.3.1   ❯  4.5.6   https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-babel#readme
(*) @vue/cli-plugin-e2e-nightwatch devDep  4.3.1   ❯  4.5.6   https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-e2e-nightwatch#readme
(*) @vue/cli-plugin-eslint devDep          4.4.1   ❯  4.5.6   https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-eslint#readme        
(*) @vue/cli-plugin-pwa devDep             4.3.1   ❯  4.5.6   https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-pwa#readme
(*) @vue/cli-plugin-typescript devDep      4.3.1   ❯  4.5.6   https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-typescript#readme    
(*) @vue/cli-plugin-unit-mocha devDep      4.3.1   ❯  4.5.6   https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-unit-mocha#readme    
(*) @vue/cli-service devDep                4.3.1   ❯  4.5.6   https://cli.vuejs.org/
(*) @vue/eslint-config-typescript devDep   5.0.2   ❯  5.1.0   https://github.com/vuejs/eslint-config-typescript#readme
(*) @vue/test-utils devDep                 1.0.2   ❯  1.1.0   https://github.com/vuejs/vue-test-utils#readme
(*) eslint devDep                          7.1.0   ❯  7.9.0   https://eslint.org
(*) lint-staged devDep                     10.2.2  ❯  10.3.0  https://github.com/okonet/lint-staged#readme

Major Update Potentially breaking API changes. Use caution.
(*) vue-property-decorator                   8.4.2  ❯  9.0.0   https://github.com/kaorun343/vue-property-decorator#readme
(*) @types/mocha devDep                      7.0.2  ❯  8.0.3   https://github.com/DefinitelyTyped/DefinitelyTyped
(*) @typescript-eslint/eslint-plugin devDep  3.0.2  ❯  4.1.1   https://github.com/typescript-eslint/typescript-eslint#readme
(*) @typescript-eslint/parser devDep         3.0.2  ❯  4.1.1   https://github.com/typescript-eslint/typescript-eslint#readme
(*) sass-loader devDep                       8.0.2  ❯  10.0.2  https://github.com/webpack-contrib/sass-loader
(*) typescript devDep                        3.9.2  ❯  4.0.2   https://www.typescriptlang.org/

出现错误

我使用了全选更新后,大概更新到一半后出现了如下错误。虽然出现了错误,但是我丝毫不慌,因为我知道大概率是更新项的问题。

npm ERR! code ENOTFOUND
npm ERR! errno ENOTFOUND
npm ERR! network request to https://registry.npm.taobao.org/colorette/download/colorette-1.2.1.tgz?cache=0&sync_timestamp=1593955763917&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolorette%2Fdownload%2Fcolorette-1.2.1.tgz failed, reason: getaddrinfo ENOTFOUND registry.npm.taobao.org
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'

所以我选择了分批次更新。

分批次更新

  1. 第一次
    • vue
    • vue-class-component
    • @types/chai
    • vue-template-compiler
  2. 第二次
    • vue-router
    • vuex
  3. 第三次
    • @vue/cli-plugin-babel
    • @vue/cli-plugin-e2e-nightwatch
    • @vue/cli-plugin-eslint
    • @vue/cli-plugin-pwa
    • @vue/cli-plugin-typescript
    • @vue/cli-plugin-unit-mocha
  4. 第四次
    • @vue/cli-service
    • @vue/eslint-config-typescript
    • @vue/test-utils
    • eslint
    • lint-staged
  5. 第五次
    • vue-property
    • @types/mocha
    • @typescript-eslint/eslint-plugin
    • @typescript-eslint/parser
    • sass-loader
    • typescript

分批次更新后不再出现报错信息,而且比批量全选更新更快。

使用 composition-api 来获得 Vue 3.0 的能力

接下来就可以在项目中加入 CompositionAPI 了,Vue 通过插件 API 的方式来让 2.x 版本支持和使用 3.0 的能力。

具体可以查看相关介绍文档

composition-api.vuejs.org/zh/
github.com/vuejs/compo…

安装 composition-api

npm install @vue/composition-api

使用 composition-api

安装过程中如果没有报错信息的话,那么现在就可以在你的 main.js/main.ts 中加入如下代码:

import VueCompositionAPI from '@vue/composition-api';
Vue.use(VueCompositionAPI);

但是这里并不是终点,所以需要对代码进行更改。

代码更改

CompositionAPI 给我们带来了新的能力,但是在 2.x 中对于使用 TypeScript 来编写的项目还是挺友好的。但还需要注意一些地方。

  1. CompositionAPIvue-property-decorator 可以在项目中共存,但是不能同时存在于同一个组件内。
  2. 编写方式的差异,会导致一个项目内存在多个编写风格,不熟悉的成员/同事会增加阅读成本。
  3. 可以渐进过度升级到 Vue 3.0 但是这个重构成本,时间周期较大。

差异对比

composition-api

import { defineComponent } from '@vue/composition-api';
export default defineComponent({
  name: 'Test',
  component: {},
  setup () {}
  // ……
});

vue-property-decorator

// https://github.com/kaorun343/vue-property-decorator
import { Vue, Component } from 'vue-property-decorator';
@Component({
  component: {},
  // ……
})
export default class Test extends Vue {
  name: 'Test',
}

代码修改

Vue 2.x TypeScript vue-property-decorator

Vue2.x TypeScript CompositionAPI

从使用上来说 CompositionAPIvue-property-decorator 是冲突的,因为在 Vue 3.0 中组件代码部分是使用 CompositionAPI 中的 defineComponent 而与原来 Vue 2.x 中使用 vue-property-decorator 的差异较大。

使用 CompositionAPI 是能够对 TypeScript 更好的类型推导 支持,以及减少更多的副作用。但是目前来说 CompositionAPI 还是向下提供支持了原来的的生命周期以及定义方式,这点确实很赞!

简单总结一下

在这个升级过程中并没碰到太多问题,一切都太顺利了,以至于我一直在想 “为什么还没报错?我好慌啊!赶紧报个错压压惊吧!”。 Vue 3.0 将 Provide/Inject 的能力提升到了基础层面从而带来了新能力,可以作为 Vuex 替代方案,也就有些小伙伴认为太像 ReactJS Hooks 了。

当然 CompositionAPI 中也提供了 ref, reactive, watchEffect 等这些新的特性能力。

Vuex 4.0 当然也做了针对于 Vue 3.0 的支持更新。

最后祝福小伙伴们都能顺利升级!


补充更新

1. 使用 CLI 创建 Vue 3.0 项目必要条件

时间:2020-09-19 11:45

如果想全新创建一个 Vue 3.0 的项目那么 @vue/cli 就要升级到 4.5+ 版本

Global 环境

Minor Update New backwards-compatible features.
(*) @vue/cli  4.4.6  ❯  4.5.6  https://github.com/vuejs/vue-cli#readme

2. 错误信息出现的原因

时间:2020-09-21 16:56 周末下午让学习小组成员同步项目,并且尝试使用上面的步骤升级会频繁出现错误信息最终原因已经可以确定。

  1. 网络波动,批量更新需要选择更少的更新项,能确定这点因为是当时连接的店里的 WIFI
  2. 全量更新必定会出现错误,这和 npm 更新机制有关,所以还是建议分批更新

3. node-sass 替换为 sass

时间:2021-02-19

官方不再推荐使用 node-sasssass 使用了 Dart 替换掉了 node 来实现,拥有更快的速度和更便捷安装方式也更易于集成。

Dart Sass is the primary implementation of Sass, which means it gets new features before any other implementation. It's fast, easy to install, and it compiles to pure JavaScript which makes it easy to integrate into modern web development workflows. Find out more or help out with its development on GitHub.
sass-lang.com/dart-sass

node-sass 也更新了警告说明


错误记录

1. 【ESLint】意外触发 no-shadow 规则

时间:2020-09-17 18:42

{
-  "eslint": "^7.1.0"
+  "eslint": "^7.9.0" // 升级后导致的问题
}

原因:eslint 更新之后定义的 enum 会意外触发 no-shadow 规则。
操作步骤:确认能够 npm run serve 之后执行 npm run lint 控制台会出现如下错误信息。

error: 'enum' is already declared in the upper scope (no-shadow) at src\utils\文件.ts:1:6:
> 1 | enum dataTypeEnum {
    |      ^
  2 |   // null = 'null',
  3 |   // undefined = 'undefined',
  4 |   string = 'string',


1 error found.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! 项目@0.1.0 lint: `vue-cli-service lint`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the 项目@0.1.0 lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output 
above.

解决方案:暂时关闭 no-shadow 规则,或者使用行注释关闭对 enum 部分的 no-shadow 检查。

2. 【stylint】意外触发校验失败

时间:2021-02-11 16:56

{
-  "stylelint": "^13.7.0" // 因版本导致的问题
+  "stylelint": "^13.10.0"
}

解决方案:将 stylelint 升级到 13.10.0 重新运行命令即可

一查 issues 刚好当天发布的新版本解决了这个问题

3. 【sass-loader】 因版本过高导致的错误

时间:2021-02-22 21:56

{
-  "sass-loader": "^11.0.1" // 因版本过高导致的问题
+  "sass-loader": "^10.1.0"
}

重新整理了项目引入库和简单的版本升级后,重新启动项目后报出如下错误

去翻了一下 webpack-contrib/sass-loader 的更新记录,发现是因为升级后他们更改了内部的实现导致的问题。

所以如果你在使用 Vue-cli 创建的 Vue 2.x 版本的项目那么不要尝试将 sass-loader 升级到 10.1.1 以上的版本。

我通过 npm i sass-loader@10.1.0 降级后,重新启动项目不会引发此错误信息。


本文会持续更新,在这个过程中遇到的问题都会整理出来更新记录。

有兴趣的小伙伴可以追一追😁