news 2026/10/17 2:45:09

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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.envTS 会报类型不存在,在env.d.ts声明
/// <reference types="vite/client" /> interface ImportMetaEnv { readonly VITE_BASE_URL: string } interface ImportMeta { readonly env: ImportMetaEnv }
  1. axios 请求封装
    request.js → request.ts,定义请求返回泛型,统一接口返回格式。
  2. 第三方缺少类型包
    有些老插件没有 TS 类型:declare module 'xxx'在.d.ts声明,关闭类型检查。
  3. 静态资源:图片 / 字体.d.ts添加:
declare module '*.png' declare module '*.jpg'

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

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

十、常见坑提前说

  1. @别名路径飘红:tsconfig.jsonpaths没配置好
  2. .vue文件报找不到模块:缺少declare module '*.vue'
  3. __dirname报错:缺少@types/node
  4. 打包失败:忘记在 package.json build 脚本添加vue-tsc
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 2:44:12

page_alloc pageset_update

pageset_update() 是 PCP&#xff08;Per-CPU Pages&#xff09;缓存配置的底层写入函数&#xff0c;负责在运行时安全地更新某个 CPU 的 PCP 参数&#xff08;batch、high_min、high_max&#xff09;。核心实现static void pageset_update(struct per_cpu_pages *pcp, unsigne…

作者头像 李华
网站建设 2026/10/17 2:44:08

从零开始学 Agent 开发:小白程序员转行的进阶指南

本文针对想转行做 Agent 开发的程序员&#xff0c;强调 Agent 开发首先是一项工程工作&#xff0c;重点不在模型调用本身&#xff0c;而在于模型调用前后。文章建议通过一个完整项目实践&#xff0c;深入理解运行时、工具、上下文、技能等核心概念&#xff0c;熟练掌握至少一个…

作者头像 李华
网站建设 2026/10/17 2:42:42

变频水泵控制器原理选型与应用指南

摘要&#xff1a;变频水泵控制器是泵房自动化改造中的核心硬件&#xff0c;依托闭环 PID 变频调速&#xff0c;改变传统阀门节流调压模式&#xff0c;实现按需调速与节能运行。本文从工作原理、核心功能、硬件参数、行业应用、选型安装维护几个角度做技术梳理&#xff0c;适合给…

作者头像 李华
网站建设 2026/10/17 2:42:28

每个孩子都左小右大,为什么还不是BST?2022年408的祖先约束

这道题要判断一棵二叉树是不是二叉搜索树。原题用数组存树&#xff0c;结点值都是正整数&#xff0c;-1表示空位。 我先想到的是逐个检查&#xff1a;左孩子比当前结点小&#xff0c;右孩子比当前结点大。一路检查下去&#xff0c;哪里不满足&#xff0c;就返回false。 这个办…

作者头像 李华
网站建设 2026/10/17 2:41:29

基于MP2642GR-Z与MKV58F1M0VLQ24的两串电池被动均衡方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 2:39:40

从终端到桌面:Kimi Code Desktop如何重构AI编程工作流

AI编程工具这两年的变化&#xff0c;快得有点超出预期。2023年大家还在讨论Copilot式的代码补全&#xff0c;2024年终端里的Agent开始能自己读仓库、改文件、跑命令&#xff0c;到了2025年&#xff0c;这类工具已经从终端往桌面迁移了——Kimi Code Desktop的发布&#xff0c;就…

作者头像 李华