小型Node/Express项目TypeScript编译异常缓慢求助
小Node/Express项目TypeScript编译极慢,处理文件数远超预期
项目基本情况
项目规模极小,仅25个TS文件,约2600行代码:
ls src/**/*.ts | wc -l 25 cat src/**/*.ts | wc -l 2618
编译诊断结果
在项目根目录执行tsc --diagnostics,输出如下:
Files: 1629 <---- 这是怎么回事? Lines: 2347286 Identifiers: 1749641 Symbols: 997960 Types: 245321 Instantiations: 70082 Memory used: 1820643K <---- 这也太夸张了? I/O read: 1.08s I/O write: 0.02s Parse time: 11.13s Bind time: 4.24s Check time: 9.11s Emit time: 0.14s Total time: 24.62s
问题核心
明明是小项目,却处理1629个文件,占用1.8G内存,编译耗时24秒;性能较弱的机器上甚至要6分钟,还得调高内存限制。怀疑TypeScript在编译整个node_modules,但exclude配置无效,试过多种glob排除模式,也把配置升级到了es2022,都没解决。
已尝试的优化(无效果)
添加以下配置后,编译时间、内存占用和处理文件数完全没变化:
"types": [], "skipLibCheck": true
项目配置文件
package.json
{ "name": "server", "version": "0.0.1", "description": "audio diary server", "main": "./build/src/index.js", "type": "module", "devDependencies": { "@types/cron": "^2.0.0", "@types/jsonwebtoken": "^8.5.9", "@types/jwk-to-pem": "^2.0.1", "@types/multer": "^1.4.7", "@types/node": "^18.7.18", "@types/node-fetch": "^2.6.3", "@types/passport": "^1.0.7", "@types/passport-google-oauth2": "^0.1.4", "@typescript-eslint/eslint-plugin": "^5.37.0", "@typescript-eslint/parser": "^5.37.0", "eslint": "^8.23.1", "eslint-plugin-react": "^7.31.8", "sucrase": "^3.29.0", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", "typescript": "^5.0.4" }, "dependencies": { "@aws-sdk/client-s3": "^3.32.0", "@mailchimp/mailchimp_marketing": "^3.0.80", "@sendgrid/mail": "^7.7.0", "aws-sdk": "^2.1183.0", "axios": "^0.27.2", "cors": "^2.8.5", "cron": "^2.1.0", "dotenv": "^16.0.1", "express": "^4.17.1", "filereader": "^0.10.3", "fs": "^0.0.1-security", "get-audio-duration": "^3.1.1", "googleapis": "^92.0.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", "mysql": "^2.14.1", "openai": "^3.2.1", "reflect-metadata": "^0.1.10", "typeorm": "0.2.41" } }
tsconfig.json
{ "compilerOptions": { "lib": ["es2022", "dom"], "module": "es2022", "moduleResolution": "node", "target": "es2022", "outDir": "./build", "rootDir": "./src", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true }, "exclude": ["node_modules"], "include": ["src/**/*"] }
解决思路及方案
- 精准控制类型文件加载
默认情况下TypeScript会扫描node_modules/@types下所有类型文件,即使配置了exclude也无效。可以通过typeRoots显式指定只加载项目必需的类型:
"compilerOptions": { // ...其他配置 "typeRoots": ["./node_modules/@types/node", "./node_modules/@types/express"] }
配合types: []使用,能彻底避免加载多余类型文件。
- 关闭
emitDecoratorMetadata(非必需时)
该选项会让TypeScript编译时生成大量元数据,对性能影响极大。如果项目不是必须依赖它(比如部分ORM场景),直接关闭:
"emitDecoratorMetadata": false
若确实需要,升级TypeScript到最新稳定版,新版本对装饰器元数据生成有性能优化。
排查意外引入的
node_modules文件
有些依赖包未编译为JS,若代码中直接导入了其TS源文件(如import xxx from 'xxx/src/index.ts'),会被纳入编译范围。执行tsc --listFiles查看所有被处理的文件,找出来自node_modules的文件并修正导入路径。优化
lib配置
Node项目不需要dom库,移除后减少TypeScript加载的库文件数量:
"lib": ["es2022"]
- 开启增量编译
让TypeScript只编译变化的文件,大幅提升后续编译速度:
"compilerOptions": { // ...其他配置 "incremental": true, "tsBuildInfoFile": "./build/.tsbuildinfo" }
- 检查依赖版本兼容性
TypeScript 5.0.4与旧版依赖(如typeorm 0.2.41)可能存在兼容性问题,导致编译时额外处理大量文件。可尝试降级TS到4.x版本,或升级依赖到兼容TS5的版本(如TypeORM 0.3+)。
内容的提问来源于stack exchange,提问作者DaraJ
相关产品推荐
相关产品推荐

