Docker中默认Yarn引发tsc rootDir错误(TS6059)的技术咨询
问题根源分析
咱们先把两个问题的底层原因拆解清楚:
TS6059报错的本质:你的
tsconfig.json里开启了allowJs: true,而Node镜像默认在/opt目录预装了yarn-v1.21.1(里面有大量.js文件)。当你在/opt目录执行tsc时,TypeScript会扫描当前工作目录下所有符合规则的文件——包括yarn-v1.21.1里的.js,但这些文件不在你指定的rootDir(/opt/src)范围内,直接触发了"rootDir需包含所有源文件"的规则错误。本地没这个问题,是因为你本地的Yarn安装目录不在项目工作目录里,TS根本扫不到它。改rootDir为
./后输出目录混乱:当把rootDir设为当前目录(/opt),TS会将工作目录下所有被包含的文件(包括src和yarn-v1.21.1)按照原目录结构完整映射到outDir(dist)里,自然就出现了dist/src/app.js和dist/yarn-v1.21.1这种不符合预期的结构。
推荐解决方案
方案1:调整Docker工作目录到源码目录(最干净的长期方案)
修改你的Dockerfile,直接把工作目录设为/opt/src,让TS的扫描范围彻底和Yarn目录隔离:
FROM node:13.8.0-alpine WORKDIR /opt/src # 将工作目录切换到源码目录 COPY package*.json ./ COPY tsconfig*.json ./ RUN npm i --quiet COPY src ./src # 别忘了把你的源码文件复制进来
同时保持tsconfig.json的原有配置不变(rootDir: "src"):
{ "compilerOptions": { "target": "es5", "module": "commonjs", "lib": ["es6"], "allowJs": true, "outDir": "dist", "rootDir": "src", "strict": true, "noImplicitAny": true, "esModuleInterop": true, "resolveJsonModule": true } }
这样执行tsc时,TS只会处理src下的文件,编译后直接输出到dist/app.js,完全符合你的预期。
方案2:在tsconfig中排除Yarn目录(快速临时修复)
如果暂时不想调整Docker工作目录,可以在tsconfig.json里添加exclude选项,明确排除Yarn的目录:
{ "compilerOptions": { // 保持原有配置不变 }, "exclude": ["node_modules", "dist", "/opt/yarn-v1.21.1"] }
这样TS就不会扫描这个Yarn目录,既不用修改rootDir,也能避免报错。不过这种方式不够优雅,后续如果镜像新增其他目录,可能还会出现类似问题。
内容的提问来源于stack exchange,提问作者Hard-Boiled Wonderland

