从零搭建TypeScript工程

如果你刚开始接触TypeScript,很容易停留在“写类型+tsc编译”的阶段。但在真实工程中,TypeScript从来不是一个“语言孤岛”,而是一整套工程体系。本文会带你从零搭建一个项目模板,覆盖完整工具链。
1. 初始化项目
1.1 创建项目
|
|
1.2 安装TypeScript
|
|
初始化配置:
|
|
1.3 推荐tsconfig配置
一个常用配置如下:
tsconfig.json是TypeScript项目的核心配置文件,它决定了TypeScript编译器(tsc)如何解析代码、如何进行类型检查、如何生成JavaScript,以及项目的模块化、目标环境等。
1.3.1 整体结构
| 配置节点 | 作用 | 示例 |
|---|---|---|
compilerOptions |
TypeScript 编译选项(核心) | {"strict":true} |
include |
指定需要编译的文件 | ["src/**/*"] |
exclude |
指定排除的文件 | ["node_modules"] |
extends |
继承其他配置文件 | "./base.json" |
files |
明确指定编译文件列表 | ["src/main.ts"] |
references |
项目引用,用于大型项目拆分 | [{path:"./core"}] |
1.3.2 compilerOptions核心配置
1.3.2.1 JavaScript输出相关
| 配置 | 作用 | 常用值 | 推荐 |
|---|---|---|---|
target |
指定生成 JavaScript 版本 | ES5、ES2015、ES2020、ES2022 |
Node.js:ES2022;Web:ES2017+ |
module |
指定模块系统 | CommonJS、ESNext、NodeNext |
前端:ESNext;Node:NodeNext |
moduleResolution |
模块解析策略 | node、node16、nodenext、bundler |
Vite:bundler;Node:NodeNext |
lib |
指定运行环境 API 类型 | DOM、ES2022 |
根据环境配置 |
jsx |
JSX 转换方式 | react、react-jsx、preserve |
React18:react-jsx |
jsxFactory |
JSX 工厂函数 | React.createElement |
React旧项目 |
jsxImportSource |
自动 JSX 导入源 | react |
React生态 |
1.3.2.2 类型检查相关
| 配置 | 作用 | 示例 | 推荐 |
|---|---|---|---|
strict |
开启所有严格检查 | true |
必开 |
strictNullChecks |
严格检查 null/undefined | true |
开启 |
strictFunctionTypes |
严格函数参数检查 | true |
开启 |
strictPropertyInitialization |
检查类属性初始化 | true |
开启 |
noImplicitAny |
禁止隐式 any | true |
开启 |
noImplicitThis |
禁止隐式 this | true |
开启 |
alwaysStrict |
输出 "use strict" |
true |
推荐 |
useUnknownInCatchVariables |
catch变量默认为unknown | true |
推荐 |
1.3.2.3 代码质量检查
| 配置 | 作用 | 示例 |
|---|---|---|
noUnusedLocals |
禁止未使用变量 | true |
noUnusedParameters |
禁止未使用参数 | true |
noImplicitReturns |
要求函数所有路径返回 | true |
noFallthroughCasesInSwitch |
禁止 switch 穿透 | true |
allowUnreachableCode |
是否允许不可达代码 | false |
exactOptionalPropertyTypes |
严格可选属性类型 | true |
1.3.2.4 输出文件相关
| 配置 | 作用 | 示例 | 用途 |
|---|---|---|---|
outDir |
输出目录 | "./dist" |
生产构建 |
rootDir |
源码根目录 | "./src" |
控制目录结构 |
sourceMap |
生成 sourcemap | true |
调试 |
inlineSourceMap |
内联 sourcemap | true |
调试 |
declaration |
生成 .d.ts 文件 |
true |
开发 npm 包 |
declarationMap |
生成声明文件 map | true |
库调试 |
removeComments |
删除注释 | true |
生产优化 |
newLine |
输出换行符 | LF/CRLF |
跨平台 |
1.3.2.5 模块导入相关
| 配置 | 作用 | 示例 | 使用场景 |
|---|---|---|---|
esModuleInterop |
增强 ES Module/CommonJS 兼容 | true |
Node项目常用 |
allowSyntheticDefaultImports |
允许默认导入 | true |
配合esModuleInterop |
resolveJsonModule |
允许导入 JSON | true |
配置文件读取 |
allowImportingTsExtensions |
允许 ts 后缀导入 | true |
特殊场景 |
verbatimModuleSyntax |
保持 import/export 原样 | true |
现代项目推荐 |
1.3.2.6 路径配置
| 配置 | 作用 | 示例 |
|---|---|---|
baseUrl |
模块搜索根目录 | "./" |
paths |
路径别名 | "@/*":["src/*"] |
rootDirs |
多个虚拟根目录 | ["src","generated"] |
typeRoots |
指定类型声明目录 | ["./types"] |
types |
指定加载类型包 | ["node"] |
示例:
使用:
|
|
1.3.2.7 性能优化相关
| 配置 | 作用 | 效果 |
|---|---|---|
skipLibCheck |
跳过第三方 .d.ts 检查 |
提高编译速度 |
incremental |
增量编译 | 大型项目加速 |
tsBuildInfoFile |
指定增量缓存文件 | 配合 incremental |
composite |
支持项目引用 | 大型 Monorepo |
disableSourceOfProjectReferenceRedirect |
禁用引用跳转 | 大型项目 |
1.3.3 include配置
| 配置 | 作用 |
|---|---|
src/**/* |
包含 src 下所有文件 |
src/**/*.ts |
只包含 ts 文件 |
src/**/*.tsx |
只包含 tsx 文件 |
示例:
1.3.4 exclude配置
| 目录 | 作用 |
|---|---|
| node_modules | 第三方代码 |
| dist | 编译产物 |
| build | 构建目录 |
| coverage | 测试覆盖率 |
示例:
2. 标准项目结构
一个可维护的TypeScript项目,一定要从结构开始规范:
-
my-ts-project/
-
src/
- modules/
- utils/
- types/
- index.ts
- app.ts
-
src/
- tests/
- dist/
- package.json
- tsconfig.json
modules:业务模块utils:纯函数工具types:全局类型services:外部接口调用
3. 开发工具链
3.1 运行TypeScript(开发环境)
安装:
|
|
运行:
|
|
3.2 监听模式开发
|
|
4. 代码规范(ESLint + Prettier)
ESLint主要关注代码质量——它用于发现Bug、强制执行最佳实践以及捕获常见错误。Pettier则关注于代码格式化。比如:空格、换行、引号等。虽然目标不同,但在格式规则方面可能存在一些重叠。分别运行它们可能会产生冲突。例如Pettier刚修改了某种格式,此时ESLint认为这种格式不符合规则并报错。解决方案是将它们集成起来,让Pettier负责所有格式化工作,ESLint负责代码质量检测。
每个包的作用如下:
| 包 | 作用 |
|---|---|
eslint |
核心代码检查引擎 |
@typescript-eslint/parser |
让 ESLint 能够理解 TypeScript 语法 |
@typescript-eslint/eslint-plugin |
提供 TypeScript 专用的 ESLint 检查规则 |
prettier |
代码格式化工具 |
eslint-config-prettier |
禁用那些与 Prettier 冲突的 ESLint 规则 |
eslint-plugin-prettier |
将 Prettier 作为 ESLint 的一条规则来运行 |
4.1 安装ESLint
|
|
ESLint 9+配置,在项目根目录下新建eslint.config.js文件:
|
|
4.2 Prettier格式化工具
|
|
.prettierrc文件内容如下:
创建.prettierignore文件跳过不需要格式化的文件。
|
|
4.3 ESLint + Prettier集成
|
|
4.4 VSCode集成
安装ESLint和Prettier扩展,配置VSCode保存时格式化。在项目中增加.vscode/settings.json。
4.5 NPM脚本
在package.json中添加脚本,以便手动运行代码检查。
5. 测试
推荐使用Vitest。
|
|
示例测试:
|
|
package.json中增加脚本:
6. 构建工具
TypeScript不负责构建,需要外部工具。
方案1:tsc (基础方案)
|
|
缺点:
- 构建慢
- 不支持现代打包能力
方案2:esbuild (高性能)
|
|
特点:
- 极速构建
- 适合中大型项目
方案3:tsup
|
|
优点:
- 零配置
- 适合库开发
7. 调试(VSCode)
创建.vscode/launch.json:
8. 环境变量管理
安装dotenv:
|
|
使用:
|
|
9. Git工程规范
Husky(Git hooks)
|
|
commitlint (提交规范)
|
|
10. Monorepo工程化
当开始写多个项目时,比如:
- 后端API
- 前端Web
- 公共工具库
- 类型共享包
很快我们就会遇到一些问题:
- ❌ 代码无法复用
- ❌ 每个项目都要独立配置一套 TypeScript / ESLint / 构建工具
- ❌ 依赖管理混乱
于是Monorepo出现了。
10.1 什么是Monorepo?
Monorepo(单仓库多项目)指的是在一个 Git 仓库中管理多个项目(packages)。Vue.js就是一个典型的Monorepo。
结构通常如下:
-
repo/
-
apps/
- web/
- api/
-
packages/
- shared/
- utils/
- types/
-
apps/
- package.json
- pnmp-workspace.yaml
10.2 为什么用用Mongorepo?
✔️ 优势
- 代码复用(shared 包)
- 类型统一(types 包)
- 依赖统一管理
- 版本一致性
- 更适合团队开发
❌ 不适合场景
- 只有一个小项目
- 没有复用需求
- 不准备长期维护
10.3 初始化Mongorepo
10.3.1 安装pnpm
|
|
10.3.2 初始化项目
|
|
10.3.3 创建workspace
pnpm-workspace.yaml
|
|
10.4 创建项目结构
-
repo/
-
apps/
- web/
- api/
-
packages/
- shared/
- utils/
- types/
-
apps/
- package.json
- pnmp-workspace.yaml
10.5 创建共享包(shared)
|
|
示例代码:
|
|
在app中使用:
|
|
10.6 配置 TypeScript Monorepo
根目录tsconfig.json:
每个包的tsconfig.json
10.7 使用Turborepo
安装
|
|
turbo.json
package.json
推荐
参考
相关内容
- json-server源码剖析:快速构建REST API背后的原理
- Node.js 源码剖析:非阻塞世界的引擎密码
- 如何解决 Node.js 中的 EMFILE 错误
- Axios:高效网络请求实战
- launch-editor源码剖析:快速打开编辑器的实现原理
支付宝
微信