从零搭建TypeScript工程

如果你刚开始接触TypeScript,很容易停留在“写类型+tsc编译”的阶段。但在真实工程中,TypeScript从来不是一个“语言孤岛”,而是一整套工程体系。本文会带你从零搭建一个项目模板,覆盖完整工具链。

1. 初始化项目

1.1 创建项目

1
2
3
mkdir my-ts-project
cd my-ts-project
npm init -y

1.2 安装TypeScript

1
npm install typescript -D

初始化配置:

1
npm tsc --init

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 版本 ES5ES2015ES2020ES2022 Node.js:ES2022;Web:ES2017+
module 指定模块系统 CommonJSESNextNodeNext 前端:ESNext;Node:NodeNext
moduleResolution 模块解析策略 nodenode16nodenextbundler Vite:bundler;Node:NodeNext
lib 指定运行环境 API 类型 DOMES2022 根据环境配置
jsx JSX 转换方式 reactreact-jsxpreserve 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
import User from "@/models/User"
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
  • tests/
  • dist/
  • package.json
  • tsconfig.json
  • modules:业务模块
  • utils:纯函数工具
  • types:全局类型
  • services:外部接口调用

3. 开发工具链

3.1 运行TypeScript(开发环境)

安装:

1
npm install tsx -D

运行:

1
npx tsx src/index.ts

3.2 监听模式开发

1
npx tsx watch src/index.ts

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

1
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin -D

ESLint 9+配置,在项目根目录下新建eslint.config.js文件:

eslint.config.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-plugin-prettier/recommended';

export default tseslint.config(
  eslint.configs.recommended,

  // TypeScript规则
  ...tseslint.configs.recommended,
  ...tseslint.configs.strictTypeChecked,

  {
    languageOptions: {
      parserOptions: {
        project: './tsconfig.json',
      },
    },
  },

  // 自定义规则
  {
    rules: {
      'no-console': 'warn',
      '@typescript-eslint/explicit-function-return-type': 'warn',
      '@typescript-eslint/no-unused-vars': [
        'error',
        { argsIgnorePattern: '^_' },
      ],
    },
  },

  prettier,

  // 忽略
  {
    ignores: ['dist/', 'build/', 'node_modules/'],
  },
);

4.2 Prettier格式化工具

1
npm install prettier -D

.prettierrc文件内容如下:

创建.prettierignore文件跳过不需要格式化的文件。

1
2
3
4
dist/
build/
node_modules/
package-lock.json

4.3 ESLint + Prettier集成

1
npm install eslint-config-prettier eslint-plugin-prettier -D

4.4 VSCode集成

安装ESLint和Prettier扩展,配置VSCode保存时格式化。在项目中增加.vscode/settings.json

4.5 NPM脚本

package.json中添加脚本,以便手动运行代码检查。

5. 测试

推荐使用Vitest

1
npm install vitest -D

示例测试:

tests/sum.test.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { describe, it, expect } from 'vitest';

function sum(a: number, b: number) {
  return a + b;
}

describe('sum function', () => {
  it('should return correct result', () => {
    expect(sum(1, 2)).toBe(3);
  });
});

package.json中增加脚本:

6. 构建工具

TypeScript不负责构建,需要外部工具。

方案1:tsc (基础方案)

1
npx tsc

缺点:

  • 构建慢
  • 不支持现代打包能力

方案2:esbuild (高性能)

1
npm install esbuild -D

特点:

  • 极速构建
  • 适合中大型项目

方案3:tsup

1
npm install tsup -D

优点:

  • 零配置
  • 适合库开发

7. 调试(VSCode)

创建.vscode/launch.json

8. 环境变量管理

安装dotenv:

1
npm install dotenv

使用:

1
2
3
import 'dotenv/config';

console.log(process.env.API_KEY);

9. Git工程规范

Husky(Git hooks)

1
npm install husky -D

commitlint (提交规范)

1
npm install commitlint -D

10. Monorepo工程化

当开始写多个项目时,比如:

  • 后端API
  • 前端Web
  • 公共工具库
  • 类型共享包

很快我们就会遇到一些问题:

  • ❌ 代码无法复用
  • ❌ 每个项目都要独立配置一套 TypeScript / ESLint / 构建工具
  • ❌ 依赖管理混乱

于是Monorepo出现了。

10.1 什么是Monorepo?

Monorepo(单仓库多项目)指的是在一个 Git 仓库中管理多个项目(packages)Vue.js就是一个典型的Monorepo。

结构通常如下:

  • repo/
    • apps/
      • web/
      • api/
    • packages/
      • shared/
      • utils/
      • types/
  • package.json
  • pnmp-workspace.yaml

10.2 为什么用用Mongorepo?

✔️ 优势

  • 代码复用(shared 包)
  • 类型统一(types 包)
  • 依赖统一管理
  • 版本一致性
  • 更适合团队开发

❌ 不适合场景

  • 只有一个小项目
  • 没有复用需求
  • 不准备长期维护

10.3 初始化Mongorepo

10.3.1 安装pnpm

1
npm install -g pnpm

10.3.2 初始化项目

1
2
3
mkdir my-monorepo
cd my-monorepo
pnpm init

10.3.3 创建workspace

pnpm-workspace.yaml

1
2
3
packages:
  - 'apps/*'
  - 'packages/*'

10.4 创建项目结构

  • repo/
    • apps/
      • web/
      • api/
    • packages/
      • shared/
      • utils/
      • types/
  • package.json
  • pnmp-workspace.yaml

10.5 创建共享包(shared)

1
2
3
mkdir -p packages/shared
cd packages/shared
pnpm init

示例代码:

1
2
3
export function formatDate(date: Date) {
  return date.toISOString();
}

在app中使用:

1
import { formatDate } from '@repo/shared';

10.6 配置 TypeScript Monorepo

根目录tsconfig.json

每个包的tsconfig.json

10.7 使用Turborepo

安装

1
2

pnpm add turbo -D

turbo.json

package.json

推荐

How To Create An NPM Package

参考

使用pnpm构建高效Monorepo:从零到一的完整指南

How to Configure ESLint and Prettier for TypeScript


相关内容

请作者喝杯咖啡!
AndyFree96 支付宝支付宝
AndyFree96 微信微信