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

编译后TypeScript在Node.js 20中找不到导出模块的问题排查

问题解决:Node.js 20运行TypeScript编译后的ES模块提示模块未找到

问题背景

使用以下tsconfig.json编译TypeScript代码:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

编译无报错,但运行node dist/server.js时出现模块未找到错误:

> node  dist/server.js

node:internal/modules/esm/resolve:255
    throw new ERR_MODULE_NOT_FOUND(
          ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'C:\Users\Documents\Development\AthletePT\dist\config\db' imported from C:\Users\Documents\Development\AthletePT\dist\server.js
    at finalizeResolution (node:internal/modules/esm/resolve:255:11)
    at moduleResolve (node:internal/modules/esm/resolve:908:10)
    at defaultResolve (node:internal/modules/esm/resolve:1121:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:396:12)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:365:25)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:240:38)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
    at link (node:internal/modules/esm/module_job:84:36) {
  code: 'ERR_MODULE_NOT_FOUND',
  url: 'file:///C:/Users/Documents/Development/AthletePT/dist/config/db'
}

Node.js v20.10.0

确认db.js存在于dist/config目录且导出正常,Node.js 18中使用node --experimental-modules --es-module-specifier-resolution=node dist/server.js可正常运行,package.json已设置"type": "module"。

原因分析

Node.js对ES模块的解析规则在版本升级后更严格:

  • ES模块规范要求导入路径必须包含完整文件扩展名(如.js)
  • Node.js 18中--es-module-specifier-resolution=node参数允许自动补全扩展名,但该参数在Node.js 20中默认关闭,且转为实验性参数
  • 当前TypeScript编译配置下,生成的JS文件中导入路径不带扩展名,导致Node.js 20无法识别

解决方案

方案1:修改TypeScript编译配置,自动添加扩展名

更新tsconfig.json的compilerOptions,将module和moduleResolution改为NodeNext:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

这样TypeScript会根据ES模块规范,自动在生成的JS文件的导入路径中添加.js扩展名,Node.js 20可正常解析。

方案2:手动在TypeScript代码中添加.js扩展名

在TS文件的导入语句中,手动加上目标JS文件的扩展名(即使源文件是.ts):

// 原导入:import db from './config/db'
import db from './config/db.js'

编译后生成的JS文件会保留这个扩展名,Node.js可正确识别。

方案3:使用Node.js实验性参数临时解决(不推荐生产环境)

运行时添加--experimental-specifier-resolution=node参数,让Node.js自动补全扩展名:

node --experimental-specifier-resolution=node dist/server.js

注意:该参数为实验性功能,未来可能被移除,不建议在生产环境使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:05:59