最近在迁移一个 Vue 2 项目,弄得差不多想起还是有必要整上 TypeScript,但改的过程中并不想一下子把所有文件从.js
改成.ts
,那么我们可以在tsconfig.json文件
的"compilerOptions"
配置上 "allowJs": true,"noEmit": true。
前提是已经安装了 typescript,没有的话可以全局
npm install -g typescript
,或者安装在项目本地。
具体上完整干货:
- cd 到项目根目录,命令行敲上
tsc –init
,生成tsconfig.json
文件,然后修改如下(部分选项根据自己需要来):
📃tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true, // https://cn.vitejs.dev/guide/features.html#typescript-compiler-options
"module": "esnext",
"moduleResolution": "node", // 指定模块解析策略,'node' 用于 Node.js 的 CommonJS 实现
"strict": true,
"allowJs": true, // 允许编译器编译JS,JSX文件
"checkJs": true,
"noEmit": true, // 编译后不输出任何js文件
"jsx": "preserve", // 在 .tsx 中支持 JSX
"sourceMap": true, // 生成目标文件的 sourceMap 文件
"resolveJsonModule": true, // 允许导入带有“.json”扩展名的模块
"esModuleInterop": true, // CommonJS/AMD/UMD 模块导入兼容
"importHelpers": true, // 模块导入辅助,通过 tslib 引入 helper 函数,https://www.typescriptlang.org/tsconfig#importHelpers
"experimentalDecorators": true,
"skipLibCheck": true, // 跳过库声明文件的类型检查
"allowSyntheticDefaultImports": true, // 允许如 import React from "react" 这样的默认导入(从没有设置默认导出的模块中默认导入)
"suppressImplicitAnyIndexErrors": true, // 禁止报告对象索引的隐式 anys 错误
"baseUrl": "./", // 非绝对地址的模块会基于这个目录去解析,默认值是当前目录
"types": ["node", "vite/client"], // 指定加载【哪些】声明文件包,如不设置此项,默认会加载全部能找到的 node_modules/@types/xxx 包
// "vite/client"用于 vite 项目中的一些类型定义补充,https://www.typescriptlang.org/tsconfig#types
"isolatedModules": true, // https://cn.vitejs.dev/guide/features.html#typescript-compiler-options
"paths": {
// 配置具体如何解析 require/import 的导入,值是基于 baseUrl 路径的映射列表。https://www.typescriptlang.org/tsconfig#paths
"@/*": ["src/*"],
// ...
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"] // 编译时引入的 ES 功能库
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"] // 解析时跳过的文件
}
- 在 src 目录下添加一个 d.ts 声明文件:
如 📃src/shims-vue.d.ts
/// <reference types="vite/client" />
// 定义 *.vue 文件的类型,否则 import 所有 *.vue 文件都会报错
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
// ...
这会和compilerOptions.types
的"vite/client"
项一起,提供以下类型定义补充:
- 资源导入 (例如:导入一个
.svg
文件) -
import.meta.env
上 Vite 注入的环境变量的类型定义 -
import.meta.hot
上的 HMR API 类型定义
另外导入一些库的时候可能会报Cannot find module 'xxx'..
这种找不到模块的错,原因是没有找到对应的声明文件。
- 有些库如
lodash
可以通过安装类型定义包来解决:npm install -S @types/lodash
; - 若部分插件尚且没有自己的 typescript 定义文件,就在我们之前的
src/shims-vue.d.ts
里声明一下,如:
// src/shims-vue.d.ts
// remove this part after vue-count-to has its typescript file
declare module 'vue-count-to'
declare module 'vue-echarts'
然后就可以逐步将一些*.js
改成*.ts
并进行类型定义补充和修改了,可以先从main.js
做起。
关于迁移的其他报错和问题,可以参考官网的 JavaScript 迁移文档。