“package.json"不在“rootDir"下 [英] 'package.json' is not under 'rootDir'
问题描述
我正在尝试在我的 TypeScript 应用程序中导入 package.json
:
import packageJson from '../package.json';
我的 tsconfig.json
包含以下内容:
<代码>{编译器选项":{"rootDir": "./src/""outDir": "./dist/","baseUrl": ".","resolveJsonModule": 真}}
问题是当我编译这个时,我得到
<块引用>错误 TS6059:文件/path/to/package.json"不在rootDir"/path/to/app/src/"下.'rootDir' 应该包含所有源文件.
我不确定我是否理解这个问题,因为 ./src/
和 /.dist
都有相同的父 ..
,所以 TypeScript 可以不理会 import '../package.json'
并且 它可以从 rootDir
或 outDir 工作
.
无论如何,我尝试了以下方法,但结果并不令人满意:
- remove
rootDir
- 编译有效,但dist
将包含dist/src
,这是我不想要的 - remove
outDir
- 然后src
被.js
文件污染(还有.js.map
如果sourceMap
是真的) - add
@ts-ignore
- 编译停止导入../package.json
的文件
此限制的解决方法是将生成的文件保留在 dist
中,并允许从 rootDir
的父目录导入?
这是可能,结果证明,并不难.
解决方案不明显的原因是因为typescript依赖rootDir
来决定输出的目录结构(见此评论来自 Typescript 的老板),并且只能导入包含在输出或包依赖项中的代码.>
- 如果您将
rootDir
设置为项目的根目录,package.json
将被发送到outDir
的根目录并可以导入.但是随后您编译的src
文件被写入outDir/src
. - 如果将
rootDir
设置为src
,其中的文件将编译为outDir
的根目录.但是现在 编译器将没有地方发出package.json
,所以它会发出一个错误,因为项目似乎配置错误"(老板的话).
解决方案:使用单独的 Typescript 子项目
Typescript 项目由 tsconfig 文件定义,是自包含的,并且有效受其rootDir代码>.这是一件非常好的事情,因为它符合封装原则.
你可以有多个项目(例如一个主库和一组库),每个项目都在自己的目录中,并有自己的 tsconfig.它们之间的依赖关系在 tsconfig 文件中使用 Typescript Project References 声明.
<块引用>我承认,术语项目"是一个糟糕的词,因为它直观地指的是整个shebang,但是在这种情况下已经采用了模块"和包".将它们视为子项目",这样会更有意义.
我们将 src
目录和包含 package.json
的根目录视为单独的项目.每个都有自己的 tsconfig
文件.
为
src
目录提供自己的项目../src/tsconfig.json
:<代码>{编译器选项":{"rootDir": ".","outDir": "../dist/","resolveJsonModule": 真},"references": [//这就是我们声明依赖的方式{ "path": "../" }//这个项目到根目录的那个`]}
为根目录提供自己的项目.
./tsconfig.json
:<代码>{编译器选项":{"rootDir": ".","outDir": ".",//如果文件的输出路径与其 src 路径相同,则不会发出任何内容"resolveJsonModule": 真,"composite": true//依赖项目需要引用才能工作},"files": [//通过将要包含的文件列入白名单,TS 不会自动"package.json"//包含根目录下的所有源代码,这是默认值.]}
运行
tsc --build src
和瞧!这将构建
src
项目.因为它声明了对根项目的引用,所以它也会构建那个,但前提是它已经过时了.因为根 tsconfig 与outDir
具有相同的目录,tsc 将不会对package.json
做任何事情,它被配置为编译的一个文件.
这对 monorepos 来说很棒
您可以通过将模块/库/子项目放在它们自己的子目录中并为它们提供自己的 tsconfig 来隔离它们.
您可以使用项目引用显式管理依赖项,以及模块化构建:
来自链接的文档:
- 您可以大大缩短构建时间
期待已久的功能是针对 TypeScript 项目的智能增量构建.在 3.0 中,您可以将
--build
标志与tsc
一起使用.这实际上是tsc
的一个新入口点,它的行为更像是一个构建协调器,而不是一个简单的编译器.运行
tsc --build
(简称tsc -b
)将执行以下操作:- 查找所有引用的项目
- 检测它们是否是最新的
- 以正确的顺序构建过时的项目
不要担心对命令行上传递的文件进行排序 -
tsc
会在需要时对它们重新排序,以便始终首先构建依赖项.强制组件之间的逻辑分离
以新的更好的方式组织您的代码.
这也很简单:
src/tsconfig.json
即使你的根目录没有代码,这个 tsconfig 也可以放在所有的通用设置都去(其他人将从它继承),和它将启用一个简单的
tsc --build src
来构建整个项目(并使用--force
从头开始构建它).<代码>{编译器选项":{"rootDir": ".","outDir": "../build/","resolveJsonModule": 真,复合":真},//这个根项目没有自己的源文件":[],//但构建此项目将构建以下所有内容:参考": [{路径":./common"}{路径":./projectA"}//在这里包含所有其他子项目]}
src/common/tsconfig.json
因为 common 没有引用,所以导入仅限于其目录和
npm_modules
中的目标.我相信,您甚至可以通过为其提供自己的package.json
来限制后者.<代码> {编译器选项":{"rootDir": ".","outDir": "../../build/common","resolveJsonModule": 真,复合":真}}
src/projectA/tsconfig.json
projectA 可以导入 common 因为声明的引用.
<代码> {编译器选项":{"rootDir": ".","outDir": "../../build/libA","resolveJsonModule": 真,复合":真},参考": [{路径":../common"}]}
I'm trying to import package.json
in my TypeScript application:
import packageJson from '../package.json';
My tsconfig.json
contains the following:
{
"compilerOptions": {
"rootDir": "./src/"
"outDir": "./dist/",
"baseUrl": ".",
"resolveJsonModule": true
}
}
The problem is that when I compile this, I get
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'
and it would work from either rootDir
or outDir
.
Anyway, I've tried the following, with unsatisfactory results:
- remove
rootDir
- compilation works, but thedist
will containdist/src
, which I don't want - remove
outDir
- thensrc
gets polluted with.js
files (and.js.map
ifsourceMap
was true) - add
@ts-ignore
- compilation stops the the file that imports../package.json
What's the workaround for this limitation, to keep generated files in dist
, and allow importing from the parent directory of rootDir
?
This is possible, and it turns out, not hard.
The reason the solution is not obvious is because typescript relies on the rootDir
to decide the directory structure of the output (see this comment from Typescript's bossman), and only code included in the output or in package dependencies can be imported.
- If you set
rootDir
to the root of your project,package.json
gets emitted to the root ofoutDir
and can be imported. But then your compiledsrc
files get written tooutDir/src
. - If you set
rootDir
tosrc
, files in there will compile to the root ofoutDir
. But now the compiler won't have a place to emitpackage.json
, so it issues "an error because the project appears to be misconfigured" (bossman's words).
solution: use separate Typescript sub-projects
A Typescript project is defined by a tsconfig file, is self-contained, and is effectively bounded by its rootDir
. This is a very good thing, as it lines up with principles of encapsulation.
You can have multiple projects (e.g. a main and a set of libs) each in their own directory and with their own tsconfig. Dependencies between them are declared in the tsconfig file using Typescript Project References.
I admit, the term "projects" is a poor one, as intuitively it refers to the whole shebang, but "modules" and "packages" are already taken in this context. Think of them as "subprojects" and it will make more sense.
We'll treat the src
directory and the root directory containing package.json
as separate projects. Each will have its own tsconfig
file.
Give the
src
dir its own project../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` ] }
Give the root dir its own project.
./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. ] }
run
tsc --build src
and voilà!This will build the
src
project. Because it declares a reference to the root project, it will build that one also, but only if it is out of date. Because the root tsconfig has the same dir as theoutDir
, tsc will simply do nothing topackage.json
, the one file it is configured to compile.
this is great for monorepos
You can isolate modules/libraries/sub-projects by putting them in their own subdirectory and giving them their own tsconfig.
You can manage dependencies explicitly using Project References, as well as modularize the build:
From the linked doc:
- you can greatly improve build times
A long-awaited feature is smart incremental builds for TypeScript projects. In 3.0 you can use the
--build
flag withtsc
. This is effectively a new entry point fortsc
that behaves more like a build orchestrator than a simple compiler.Running
tsc --build
(tsc -b
for short) will do the following:- Find all referenced projects
- Detect if they are up-to-date
- Build out-of-date projects in the correct order
Don’t worry about ordering the files you pass on the commandline -
tsc
will re-order them if needed so that dependencies are always built first.enforce logical separation between components
organize your code in new and better ways.
It's also very easy:
src/tsconfig.json
Even if you have no code at the root, this tsconfig can be where all the common settings go (the others will inherit from it), and it will enable a simple
tsc --build src
to build the whole project (and with--force
to build it from scratch).{ "compilerOptions": { "rootDir": ".", "outDir": "../build/", "resolveJsonModule": true, "composite": true }, // this root project has no source of its own "files": [], // but building this project will build all of the following: "references": [ { "path": "./common" } { "path": "./projectA" } // include all other sub-projects here ] }
src/common/tsconfig.json
Because common has no references, imports are limited to targets within its directory and
npm_modules
. You could even restrict the latter, I believe, by giving it its ownpackage.json
.{ "compilerOptions": { "rootDir": ".", "outDir": "../../build/common", "resolveJsonModule": true, "composite": true } }
src/projectA/tsconfig.json
projectA can import common because of the declared reference.
{ "compilerOptions": { "rootDir": ".", "outDir": "../../build/libA", "resolveJsonModule": true, "composite": true }, "references": [ { "path": "../common" } ] }
这篇关于“package.json"不在“rootDir"下的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!