“package.json”不在“rootDir”下

新手上路,请多包涵

我正在尝试在我的 TypeScript 应用程序中导入 package.json

 import packageJson from '../package.json';

我的 tsconfig.json 包含以下内容:

 {
  "compilerOptions": {
    "rootDir": "./src/"
    "outDir": "./dist/",
    "baseUrl": ".",
    "resolveJsonModule": true
  }
}

问题是当我编译这个时,我得到

error TS6059: File '/path/to/package.json' is not under 'rootDir' '/path/to/app/src/'. 'rootDir' is expected to contain all source files.

I’m not sure I understand the issue, because both ./src/ and /.dist have the same parent .. , so TypeScript could just leave alone the import '../package.json' 它可以rootDiroutDir 工作。

无论如何,我尝试了以下方法,但结果不尽如人意:

  • 删除 rootDir 编译有效,但 dist 将包含 dist/src ,我不想要
  • remove outDir - then src gets polluted with .js files (and .js.map if sourceMap was true)
  • 添加 @ts-ignore 编译停止导入的文件 ../package.json

此限制的解决方法是什么,以将生成的文件保留在 dist 中,并允许从 rootDir 的父目录导入?

原文由 Kousha 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
1 个回答

这是 可能的,事实证明,这 并不难

解决方案 不明显 的原因是因为 typescript 依赖于 rootDir 来决定输出的目录结构(请参阅 Typescript’s bossman 的评论),并且只能包含在输出或包依赖项中的代码进口。

  • 如果将 rootDir 设置为项目的根目录,则 package.json 将发送到 outDir 的根目录并可以导入。但是然后你编译的 src 文件被写入 outDir/src
  • 如果将 rootDir 设置为 src ,其中的文件将编译到 outDir 的根目录。但是现在 编译器没有地方发出 package.json ,所以它发出“一个错误,因为项目似乎配置错误”(老板的话)。

解决方案: 使用单独的 Typescript 子项目

Typescript 项目tsconfig 文件定义,是独立的,并且 有效地 受其 rootDir 的约束。这是一件非常好的事情,因为它 符合封装原则

您可以有多个项目(例如一个主项目和一组库),每个项目都在它们自己的目录中,并且有它们自己的 tsconfig。它们之间的依赖关系使用 Typescript Project References 在 tsconfig 文件中声明。

我承认,术语“项目”是一个糟糕的词,因为直觉上它指的是整个 shebang,但是“模块”和“包”已经在这个上下文中使用了。将它们视为“子项目”,这样会更有意义。

我们会将 src 目录和包含 package.json 的根目录视为单独的项目。每个都有自己的 tsconfig 文件。

  1. src 目录自己的项目。

./src/tsconfig.json

    {
     "compilerOptions": {
       "rootDir": ".",
       "outDir": "../dist/",
       "resolveJsonModule": true
     },
     "references": [      // this is how we declare a dependency from
       { "path": "../" }  // this project to the one at the root dir`
     ]
   }

  1. 给根目录自己的项目。

./tsconfig.json :

    {
     "compilerOptions": {
       "rootDir": ".",
       "outDir": ".",  // if out path for a file is same as its src path, nothing will be emitted
       "resolveJsonModule": true,
       "composite": true  // required on the dependency project for references to work
     },
     "files": [         // by whitelisting the files to include, TS won't automatically
       "package.json"   // include all source below root, which is the default.
     ]
   }

  1. 运行 tsc --build src

这将构建 src 项目。因为它声明了对根项目的引用,所以它也会构建那个项目,但前提是它已过时。因为根 tsconfig 与 outDir 具有相同的目录,所以 tsc 将不会对 package.json 进行任何操作,它被配置为编译的一个文件。

这对 monorepos 来说很棒

  • 您可以通过将模块/库/子项目放在它们自己的子目录中并为它们提供自己的 tsconfig.json 来隔离模块/库/子项目。

  • 您可以使用 Project References 显式管理依赖项,以及模块化构建:

从链接文档:

  • 您可以大大缩短构建时间

    一个期待已久的功能是 TypeScript 项目的智能增量构建。在 3.0 中,您可以将 --build 标志与 tsc 一起使用。这实际上是 tsc 的新入口点,它的行为更像是一个构建协调器,而不是一个简单的编译器。

    运行 tsc --buildtsc -b 简称)将执行以下操作:

    • 查找所有引用的项目
    • 检测它们是否是最新的
    • 以正确的顺序构建过时的项目

    不要担心在命令行上对传递的文件进行排序 - tsc 将在需要时重新排序它们,以便始终首先构建依赖项。

  • 强制组件之间的逻辑分离

  • 以新的更好的方式组织您的代码。

这也很容易:

  1. tsconfig 用于共享选项并使用简单的 tsc --build 命令构建所有子项目(使用 --force 从头开始构建它们

src/tsconfig.json

    {
     "compilerOptions": {
       "outDir": ".", // prevents this tsconfig from compiling any files

       // we want subprojects to inherit these options:
       "target": "ES2019",
       "module": "es2020",
       "strict": true,
       ...
     },

     // configure this project to build all of the following:
     "references": [
       { "path": "./common" }
       { "path": "./projectA" }
     ]
   }

  1. 由于没有项目引用而无法从其他子项目导入的“公共”库

src/common/tsconfig.json

    {
     "extends": "../tsconfig.json", //inherit from root tsconfig

     // but override these:
     "compilerOptions": {
       "rootDir": ".",
       "outDir": "../../build/common",
       "resolveJsonModule": true,
       "composite": true
     }
   }


  1. 由于声明的引用,可以导入 common 的子项目。 src/projectA/tsconfig.json
    {
     "extends": "../tsconfig.json", //inherit from root tsconfig

     // but override these:
     "compilerOptions": {
       "rootDir": ".",
       "outDir": "../../build/libA",
       "resolveJsonModule": true,
       "composite": true
     },
     "references": [
       { "path": "../common" }
     ]
   }


原文由 Inigo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题