Yarn+ts-node-dev需声明src为依赖的问题解析与方案咨询
Yarn Berry下ts-node/ts-node-dev报错需声明src为依赖的原因与解决办法
环境
- Node.js v20.12.2
- Yarn 4.1.1
- TypeScript 5.4.5
问题背景
设定两个开发目标:
- 用ts-node和ts-node-dev本地运行应用
- 用tsc编译后导出至其他环境运行
目前目标2可正常执行(执行yarn build后,node dist/server.js能正常运行),但执行yarn dev或yarn start时出现报错,提示需将src文件夹声明为依赖,按提示添加后虽能运行但不符合常规逻辑,特此咨询该现象的原因及合理解决方法。
文件结构
- project home - package.json - .pnp.cjs - tsconfig.json - src - server.ts - dist - server.js
错误信息
$ yarn ts-node-dev --exit-child src/server.ts <project-root>/.pnp.cjs:7812 return Object.defineProperties(new Error(message), { ^ Error: Your application tried to access src, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. Required package: src (via "src/server.ts") Required by: <project-root>/ at makeError (<project-root>/.pnp.cjs:7812:34) at resolveToUnqualified (<project-root>/.pnp.cjs:9450:21) at resolveRequest (<project-root>/.pnp.cjs:9587:31) at <project-root>/api/.pnp.cjs:9650:26 at resolveRequest (<project-root>/.yarn/__virtual__/ts-node-dev-virtual-1a2df4f79d/6/.yarn/berry/cache/ts-node-dev-npm-2.0.0-a9d487396c-10c0.zip/node_modules/ts-node-dev/lib/resolveMain.js:11:16) at exports.resolveMain <project-root>/.yarn/__virtual__/ts-node-dev-virtual-1a2df4f79d/6/.yarn/berry/cache/ts-node-dev-npm-2.0.0-a9d487396c-10c0.zip/node_modules/ts-node-dev/lib/resolveMain.js:30:20) at exports.runDev (<project-root>/.yarn/__virtual__/ts-node-dev-virtual-1a2df4f79d/6/.yarn/berry/cache/ts-node-dev-npm-2.0.0-a9d487396c-10c0.zip/node_modules/ts-node-dev/lib/index.js:53:30) at Object.<anonymous> (<project-root>/.yarn/__virtual__/ts-node-dev-virtual-1a2df4f79d/6/.yarn/berry/cache/ts-node-dev-npm-2.0.0-a9d487396c-10c0.zip/node_modules/ts-node-dev/lib/bin.js:136:4) at Module._compile (node:internal/modules/cjs/loader:1369:14) at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
配置文件
package.json
{ "name": "test-app", "packageManager": "yarn@4.1.1", "version": "0.1.0", "description": "test-app", "scripts": { "dev": "ts-node-dev --exit-child ./src/index.ts", "start": "ts-node ./src/index.ts", "build": "tsc" }, "devDependencies": { "@tsconfig/node-lts": "^20.1.3", "@types/express": "^4", "@types/node": "^20.12.7", "ts-node": "^10.9.2", "ts-node-dev": "^2.0.0", "typescript": "^5.4.5" }, "dependencies": { "express": "^4.19.2", "graphql": "^16.8.1", "graphql-http": "^1.22.1" } }
tsconfig.json
{ "extends": "@tsconfig/node-lts/tsconfig.json", "include": ["src"], "compilerOptions": { /* Emit */ "outDir": "dist", } }
原因分析
核心原因是Yarn Berry的PnP(Plug'n'Play)模块解析机制:
- Yarn Berry的PnP会严格区分npm包和本地文件路径。当执行
ts-node-dev src/server.ts时,没有添加./前缀,Yarn会把src识别为一个npm包名称,去package.json的依赖列表里查找,找不到就抛出错误。 - 而tsc编译时,是基于
tsconfig.json的include配置直接扫描本地src目录,不受PnP的包解析逻辑限制,因此编译后运行正常。
解决方法
方法1:修改脚本路径,添加./前缀
修改package.json中的scripts,给本地路径加上./,明确告诉Yarn这是本地文件而非npm包:
"scripts": { "dev": "ts-node-dev --exit-child ./src/server.ts", "start": "ts-node ./src/server.ts", "build": "tsc" }
(注:原配置中dev脚本指向./src/index.ts,但错误信息中是src/server.ts,请根据实际文件名称统一调整)
方法2:配置ts-node使用项目tsconfig
给ts-node/ts-node-dev添加--project tsconfig.json参数,确保其使用项目的TypeScript配置进行路径解析:
"scripts": { "dev": "ts-node-dev --exit-child --project tsconfig.json ./src/server.ts", "start": "ts-node --project tsconfig.json ./src/server.ts", "build": "tsc" }
方法3:添加Yarn packageExtensions(不推荐)
如果不想修改脚本路径,可以通过Yarn的packageExtensions配置,让Yarn将src识别为本地目录,但这种方法不符合常规开发规范,仅作为临时 workaround:
在package.json中添加:
"packageExtensions": { "*": { "dependencies": { "src": "*" } } }
内容的提问来源于stack exchange,提问作者ppavlov
相关产品推荐
相关产品推荐

