likes
comments
collection
share

重构改造Javascript项目为Typescript项目

作者站长头像
站长
· 阅读数 13

项目基础信息和改造目标

之前组内有一个基于vite脚手架生成的vue3项目,功能前前后后开发了一个月,基本的业务需求已经满足,但是这个项目是一个纯JavaScript的项目,不符合大前端趋势和方向,所以我就认领了一周改造完这个项目,下面记录一下所有的改动点,欢迎讨论。

安装基础依赖

  • typescript
  • vue-tsc
  • @typescript-eslint/eslint-plugin
  • @typescript-eslint/parser

由于项目是通过vite脚手架生成的,所以基本其他配置项已经成熟了,唯一需要的依赖就是上面


修改打包命令

// node_modules不检查,打包命令加一个`–skipLibCheck`即可:
"scripts": {
    "build": "vue-tsc --noEmit --skipLibCheck && vite build"
}

tsconfig配置

{
    "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "moduleResolution": "node",
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "allowSyntheticDefaultImports": true,
        "strictFunctionTypes": false,
        "jsx": "preserve",
        "isolatedModules": true,
        "baseUrl": ".",
        "sourceMap": true,
        "esModuleInterop": true,
        "resolveJsonModule": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "experimentalDecorators": true,
        "lib": ["dom", "esnext"],
        "noImplicitAny": false,
        "skipLibCheck": true,
        "typeRoots": ["./node_modules/@types/", "./src/types/"],
        "types": ["vite/client"],
        "paths": {
            "@/*": ["src/*"]
        }
    }
    "include": [
        "src/**/*.ts",
        "src/**/*.d.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "types/**/*.d.ts",
        "types/**/*.ts",
        "vite.config.ts"
    ],
    "exclude": [
        "node_modules",
        "tests/server/**/*.ts",
        "build",
        "dist",
        "**/*.js"
    ]
}

修改eslint配置

需要增加一些对typescript规则的教验,可以依据需求后期自己增加

// eslinttrc.js
plugins: ['@typescript-eslint'],
rules: {
    '@typescript-eslint/no-var-requires': 'off',
    '@typescript-eslint/camelcase': 'off',
    '@typescript-eslint/no-unused-vars': 'warn',
    '@typescript-eslint/no-use-before-define': 'off',
    '@typescript-eslint/ban-ts-comment': 'off',
    '@typescript-eslint/ban-types': 'off',
}

增加各种描述文件

重构改造Javascript项目为Typescript项目

我是在外出项目目录下增加了一个文件夹types,里面的文件用来定义一些全局的声明和全局类型的定义

描述vue文件,大部分会起名字叫shims-vue.d.ts,还有vite项目默认会带vite-env.d.ts是为了 typescript 做的适配定义文件,因为.vue 文件不是一个常规的文件类型,ts 是不能理解 vue 文件是干嘛的,这个名字是不受限制的,我这里叫module.d.ts

// 可以根据项目自己定义
declare module '*.vue' {
    import type { DefineComponent } from 'vue';
    const component: DefineComponent<{}, {}, any>;
    export default component;
}
declare module '*.svg';
declare module '*.png';
declare module '*.jpg';
declare module '*.jpeg';
declare module '*.gif';
declare module '*.bmp';
declare module '*.tiff';

除此之外可以在global.d.ts里面定义一些全局使用的类型下面我举一些例子

// 例如定义一个全局使用的ChangeEvent interface类型
declare interface ChangeEvent extends Event {
    target: HTMLInputElement;
}

// 使用例如定义一个全局使用的ChangeEvent
function changeXXX(e: ChangeEvent) {
    XXX.value = e?.target ? parseFloat(e.target.value) : 
}

// 也可以使用原生类型,但是每个文件涉及的都需要定义
function changeXXX(e: Event) {
    XXX.value = e.target?Number((<HTMLInputElement>e.target).value): e;
}

改掉所有的js文件

  • axios封装

在项目目录util/http.js下进行封装

......AxiosInstance实例化封装,此处省略需要所有源码可评论留言
// 常用方法封装
get<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.get(url, { params });
}

post<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.post(url, params);
}

接口使用

重构改造Javascript项目为Typescript项目

在src目录下建立api文件夹,按照模块分开,每个接口定义index.ts和type.ts

/*

* @Author: xxxx
* @Date: 2022-10-26
* @Desc: 用户信息接口
*/

import request from '@/util/http';
import { UserInfoResponse } from './type';
const userInfoUrl = '/api/user';

const getUserInfo = async () => {
    const response = await request.post<UserInfoResponse>(userInfoUrl)
    return response.data;
};
export default getUserInfo;
  • vue-router修改

使用enum枚举了所有页面的路由,routes定义好RouteRecordRaw类型(从vue-router.d.ts中获取)

改造所有的vue文件为

<script setup lang="ts">

参考vue官方文档给出的标注类型认真修改

重构改造Javascript项目为Typescript项目

结语

以上该封装的封装,该修改的修改完毕,运行build命令,success完美结束,总体来说因为是使用vite生成的原始项目,改造起来还是比较方便快捷的,有遇到坑的欢迎讨论