You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决TypeScript项目中的ERR_UNKNOWN_FILE_EXTENSION错误

Node.js + TypeScript ESM 配置问题解决

我近期搭建一个使用ES6 import 语句和顶层await的Node.js项目时遇到了两个核心问题:

  • 直接用npx ts-node index.ts运行时,报错无法识别.ts扩展名:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/zhyp/Code/ts-test/src/index.ts

  • 添加--esm标志用npx ts-node --esm index.ts运行时,出现模块找不到错误:

throw new ERR_MODULE_NOT_FOUND(
^
CustomError: Cannot find module '/home/zhyp/Code/ts-test/src/imported-file' imported from /home/zhyp/Code/ts-test/src/index.ts

试过给导入加.js扩展名能运行,但用.ts扩展名需要开启allowImportingTsExtensions,同时开启noEmit又会导致tsc无法构建,求解决。

问题根源

  1. package.json中type: module的冲突:设置type: module后,Node.js默认以ESM模式处理文件,但ts-node默认是CommonJS行为,直接运行会因为Node.js不识别.ts扩展名报错。
  2. ESM的模块解析规则:Node.js的ESM要求导入必须带完整扩展名,而TypeScript默认允许省略扩展名,ts-node在ESM模式下需额外配置才能处理TypeScript文件的扩展名解析。
  3. allowImportingTsExtensions的局限性:开启该选项后,TypeScript允许导入.ts文件,但如果同时开启noEmit,tsc无法生成对应的.js文件,导致构建失败。

解决步骤

1. 调整tsconfig.json配置

添加ESM相关编译选项,兼顾运行与构建:

{
  "compilerOptions": {
    "target": "es2022",
    "module": "es2022",
    "rootDir": "src",
    "resolveJsonModule": true,
    "allowJs": true,
    "outDir": "build",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitAny": true,
    "skipLibCheck": true,
    // 新增ESM适配配置
    "moduleResolution": "node16", // 匹配Node.js的ESM解析逻辑
    "allowImportingTsExtensions": true, // 允许导入.ts扩展名
    "noEmit": false, // 关闭noEmit,确保tsc能正常构建
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

2. 更新package.json脚本

明确启动脚本使用ESM模式,添加构建命令:

{
  "name": "typescript-node",
  "version": "1.0.0",
  "description": "TypeScript Template with Node.js",
  "main": "build/index.js", // 指向构建后的产物文件
  "scripts": {
    "start": "nodemon --exec 'ts-node --esm' src/index.ts",
    "build": "tsc" // 添加正式构建脚本
  },
  "dependencies": {
    "@types/node": "14.14.29",
    "ts-node": "10.9.1",
    "typescript": "5.0.4"
  },
  "devDependencies": {
    "@types/express": "^4.17.6",
    "nodemon": "1.18.4"
  },
  "keywords": [],
  "type": "module"
}

3. 调整导入语句

保持导入使用.ts扩展名(因已开启allowImportingTsExtensions):

// index.ts
import test from "./imported-file.ts";

console.log(test);

4. 验证运行与构建

  • 开发运行:执行npm start,nodemon会通过ts-node的ESM模式启动项目,可正确解析.ts文件
  • 生产构建:执行npm run build,tsc会将源码编译到build目录,生成.js文件,直接用node build/index.js即可运行构建后的项目

补充优化

如果不想在导入中写.ts扩展名,可在tsconfig.json中添加"resolvePackageJsonExports": true和"resolvePackageJsonImports": true,同时保持moduleResolution为node16或nodenext,ts-node会自动省略扩展名的TypeScript文件。

内容的提问来源于stack exchange,提问作者zhyp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:15:15