JS 项目转 TS 项目(Vue3 + 若依这类后台项目)完整改造清单

JS 项目转 TS 项目(Vue3 + 若依这类后台项目)完整改造清单

我们当前项目:Vue3 + Vite + Pinia + ElementPlus,JS → TS,分环境安装、配置文件、代码改造、类型定义、逐步迁移5 大块,不一次性全改,支持渐进式迁移。

一、第一步:安装 TS 相关依赖

复制代码
# pnpm
pnpm add -D typescript @vitejs/plugin-vue vue-tsc @types/node

包说明:

  • typescript:ts 核心编译器
  • vue-tsc:专门校验 Vue 单文件组件<script setup>类型
  • @types/node:node 内置 API 类型(import.meta、path 等)
  • @vitejs/plugin-vue:vite 处理 vue,TS 版本也需要

二、修改 Vite 配置 vite.config.js → vite.config.ts

  1. 文件名改后缀:.js → .ts

  2. 顶部导入改成 TS 写法

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import { resolve } from 'path'

    export default defineConfig({
    plugins: [vue()],
    resolve: {
    alias: {
    '@': resolve(__dirname, 'src')
    }
    }
    })

注意:__dirname 在 TS 里需要 @types/node,否则飘红

三、新增 TS 配置文件 tsconfig.json(核心)

复制代码
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,
    /* 模块解析 */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    /* vue类型 */
    "jsx": "preserve",
    /* 类型严格度:开发推荐严格模式,不想一下子大量报错可以先false */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

同时新建 tsconfig.node.json 给 vite 配置文件用

复制代码
{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts"]
}

四、package.json 修改脚本命令

复制代码
"scripts": {
  "dev": "vite",
  "build": "vue-tsc && vite build",
  "preview": "vite preview"
}

build 前面加 vue-tsc:打包前先做类型校验,类型错误直接阻止打包。

五、Vue 单文件组件改造(重点,我们的 tags-view、驾驶舱页面都要改)

1. script 标签替换

JS 版本:

复制代码
<script setup>

TS 版本:

复制代码
<script setup lang="ts">

✅ 只加 lang="ts",文件后缀依旧是 .vue,不用改成 .ts

2. 变量、接口、类型定义

JS:

复制代码
const statData = {
  userTotal: 0,
  newsTotal: 0
}

TS:定义接口约束数据结构

复制代码
interface StatData {
  userTotal: number
  newsTotal: number
  deptTotal: number
}
const statData: StatData = reactive<StatData>({
  userTotal: 0,
  newsTotal: 0,
  deptTotal: 0
})

3. Pinia store 改造(我们的 userStore、tagsViewStore)

原 stores/user.js → stores/user.ts

复制代码
import { defineStore } from 'pinia'
interface UserState {
  token: string
  name: string
}
export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    token: '',
    name: ''
  }),
  actions: {
    setToken(val: string) {
      this.token = val
    }
  }
})

六、全局类型声明 src/types/index.d.ts(非常关键)

新建 src/types/index.d.ts,放全局类型,解决 vue 文件、第三方模块找不到类型报错

复制代码
// 识别 *.vue 文件
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

// 标签页对象类型(直接复用我们tags-view的tag类型)
export interface TagView {
  path: string
  title: string
  name?: string
}

以后所有页面都可以直接 import type { TagView } 使用

七、路由文件改造 router/index.js → router/index.ts

路由里的路由项,我们可以用 TS 内置类型 RouteRecordRaw

复制代码
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'

// 路由数组加上类型
export const constantRoutes: RouteRecordRaw[] = [
  {
    path: '/cockpit',
    name: 'Cockpit',
    component: () => import('@/views/cockpit/cockpit.vue'),
    meta: { title: '驾驶舱大屏' }
  }
]

路由 meta 自定义字段需要扩展类型,否则 meta 飘红:src/types/router.d.ts

复制代码
import 'vue-router'
declare module 'vue-router' {
  interface RouteMeta {
    title?: string
  }
}

八、其他需要处理的点

  1. 环境变量 .env
    import.meta.env TS 会报类型不存在,在 env.d.ts 声明

    ///
    interface ImportMetaEnv {
    readonly VITE_BASE_URL: string
    }
    interface ImportMeta {
    readonly env: ImportMetaEnv
    }

  2. axios 请求封装
    request.js → request.ts,定义请求返回泛型,统一接口返回格式。

  3. 第三方缺少类型包
    有些老插件没有 TS 类型:declare module 'xxx' 在 .d.ts 声明,关闭类型检查。

  4. 静态资源:图片 / 字体 .d.ts 添加:

    declare module '.png'
    declare module '
    .jpg'

九、推荐迁移策略(不要一次性全部改完!渐进式)

  1. 先搭好 tsconfig、依赖、vite 配置;此时项目依旧可以跑 JS 文件(TS 支持混写 JS+TS)
  2. 优先改核心文件:路由、pinia store
  3. 再改公共组件:tags-view(就是我们刚写右键菜单这个组件)
  4. 最后改业务页面:驾驶舱大屏等页面
  5. 全部迁移完成后,tsconfig strict:true 开启严格校验

十、常见坑提前说

  1. @ 别名路径飘红:tsconfig.json paths 没配置好
  2. .vue 文件报找不到模块:缺少 declare module '*.vue'
  3. __dirname 报错:缺少 @types/node
  4. 打包失败:忘记在 package.json build 脚本添加 vue-tsc
相关推荐
定栓1 小时前
Webpack迁到Vite第四节:SVG 图标系统
前端·webpack·node.js
Dovis(誓平步青云)1 小时前
车辆进入隧道后信号断开,座舱旅程怎样补回事件
java·开发语言·前端·数据库·电脑
定栓1 小时前
Webpack迁到Vite第六节:构建配置详解(vite.config.js)
前端·javascript·webpack
风骏时光牛马1 小时前
从零到精通AI全栈学习路线
前端
Autumn_ing10 小时前
Design.md生成UI怎么验收?举例运营后台的颜色、状态和数据核对
前端·ui·ai·设计系统·paico·ai生成ui·design.md
keyipatience11 小时前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
朱涛的自习室11 小时前
我给 Gemini 4 和 DeepSeek 搞了套「末位淘汰」,AI 干活会更猛吗?(Day 3)
android·前端·后端
java1234_小锋13 小时前
【技术专题】HTML5 网页技术 - HTML5简介 & HTML5 文档结构
前端·html·html5