ts-node无法找到依赖模块,TypeScript项目运行异常求助
问题描述
现有一个简单TypeScript项目,包含以下文件:
src/hello.js
export default function hello() { return 'Hello world' }
src/say.js
import hello from './hello.js' console.log(hello())
项目的tsconfig.json配置如下:
{ "compilerOptions": { "lib": ["es2023"], "module": "node16", "target": "es2022", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "node16", "allowSyntheticDefaultImports": true, "outDir": "dist", }, "include": ["src/**/*"] }
package.json中设置了"type": "commonjs"。使用npx ts-node src/say.ts运行时出现模块找不到的错误:
$ npx ts-node src/say.ts Error: Cannot find module './hello.js' Require stack: - /Users/pawel/wrk/github/ts-sandbox/src/say.ts at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1144:15) at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/Users/pawel/wrk/github/ts-sandbox/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30) at Function.Module._load (node:internal/modules/cjs/loader:985:27) at Module.require (node:internal/modules/cjs/loader:1235:19) at require (node:internal/modules/helpers:176:18) at Object.<anonymous> (/Users/pawel/wrk/github/ts-sandbox/src/say.ts:1:1) at Module._compile (node:internal/modules/cjs/loader:1376:14) at Module.m._compile (/Users/pawel/wrk/github/ts-sandbox/node_modules/ts-node/src/index.ts:1618:23) at Module._extensions..js (node:internal/modules/cjs/loader:1435:10) at Object.require.extensions.<computed> [as .ts] (/Users/pawel/wrk/github/ts-sandbox/node_modules/ts-node/src/index.ts:1621:12) { code: 'MODULE_NOT_FOUND', requireStack: [ '/Users/pawel/wrk/github/ts-sandbox/src/say.ts' ] }
已知用tsc编译后通过node dist/say.js可正常运行,tsx src/say.ts、tsimp src/say.ts也能正常运行,请问使用ts-node时遗漏了什么配置?
解决方案
问题核心是ts-node默认的CommonJS模式无法适配你当前的模块解析配置,以下是两种可行的解决方式:
方式一:启用ts-node的ES模块支持
- 安装依赖:
npm install --save-dev ts-node/esm @types/node typescript
- 在
package.json中添加ts-node配置:
{ "type": "commonjs", "ts-node": { "esm": true, "experimentalSpecifierResolution": "node" } }
这样ts-node会以ES模块模式运行,正确解析带.js后缀的导入路径,和tsc、tsx的解析逻辑对齐。
方式二:修改导入路径(不推荐)
临时兼容方案,把src/say.js中的导入改为不带.js后缀:
import hello from './hello'
但这种写法不符合Node.js 16+的ES模块规范,仅适配ts-node的CommonJS模式,不建议长期使用。
原因说明
tsc编译时会根据module: node16自动调整导入路径,确保输出的CommonJS代码能正确找到模块;tsx、tsimp内置了模块路径修正逻辑,自动处理混合模块场景;- ts-node默认的CommonJS模式严格遵循Node.js的CommonJS解析规则,不会自动处理ES模块风格的带
.js后缀导入,因此出现找不到模块的错误。
内容的提问来源于stack exchange,提问作者pawel-id
相关产品推荐
相关产品推荐

