Typescript: tsc 不应该关心 rootDir 之外的 ts 文件并失败

创建于 2016-07-21  ·  87评论  ·  资料来源: microsoft/TypeScript

打字稿:2.0.0

我有一个fixtures文件夹,其中包含.ts文件。 在我的tsconfig.json我将rootDirsrc ,其中包含我的所有源代码(包括测试)。

夹具文件用于测试用例。 tsc 不应该抱怨它们的存在并导致编译失败。

Working as Intended

最有用的评论

Bleh,这真的按预期工作吗? 我刚刚遇到了这个问题,我告诉打字稿我的源代码都在一个特定的文件夹中(通过rootDir )然后它继续_完全忽略我告诉它的内容_ 因为我碰巧有一个带有.ts文件

这真的感觉像是一个错误,如果我通过rootDir告诉编译器我的源代码在哪里,它不应该完全忽略该设置并更改我的输出文件夹结构,因为它认为我可能做错了什么。 它应该忽略不在rootDir任何文件。 或者,它应该很难失败,而不是继续发出与我想要的输出文件夹结构不符的输出!


对于任何跟随我的人,以下将做你_实际上_想要的:

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

所有87条评论

为了绕过,我将“排除”添加回我的tsconfig.json

rootDir 用于构建输出文件夹结构。 所有文件都必须在 rootDir 下,编译器才能知道在哪里写输出。 如果没有这个限制,如果存在不在 rootDir 下的文件,编译器有两个选项 1. 要么它们将在完全出乎意料的地方发出,要么 2. 根本不发出。 我会说错误信息比无声的失败要好得多。

@mhegazy感谢您的澄清。 通过名称rootDir我把它作为源代码的根目录,就像浏览器的baseURL 。 不知道它仅用于输出文件夹结构。

这是我的 tsconfig.json:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": true,
        "rootDir": "src",
        "outDir": "build"
    },
    "exclude": [
        ".idea",
        "build",
        "node_modules",
        "typings/globals",
        "typings/modules"
    ]
}

我的文件夹结构如下所示:

  • 项目

    • 建造

    • node_modules(符号链接到 ../node_modules)

    • 节点模块

    • 源文件

我希望 src 文件夹中的 .ts 文件被编译并以相同的文件夹结构输出到 build 文件夹。 我这样做是为了将我的文档根目录设置为构建文件夹,并将我的 src 放在文档根目录之外。 我收到有关 node_modules 文件夹中 .ts 文件的错误消息,与 OP 相同的错误消息。 注意上面,我排除了 node_modules。 为什么 tsc 抱怨这些?

@HillTravis您的问题似乎与https://github.com/Microsoft/TypeScript/issues/9552相同

@mhegazy我不确定它是一样的。 是的,我的结构包含一个符号链接,但是应该忽略该符号链接存在的任何地方。

在 #9552 中,没有 src 文件夹,这意味着正在构建的路径中存在 node_modules 文件夹。 在我的场景中,tsc 应该查看的根目录是 src,它不包含 node_modules。 所以它根本不应该查看那个文件夹。 最重要的是,我通过我的 tsconfig.json 明确排除了 node_modules 文件夹。 所以它应该被双重忽略。 我还排除了build文件夹,这应该涵盖其中的 node_modules 符号链接。

此外,在#9552 中,没有提到错误消息或编译失败。

我还应该提到我使用的是 TypeScript 1.8.10。

具体来说,错误消息如下:

错误 TS6059:文件 '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.module.ts' 不在 'rootDir' '/Users/thill/Projects/ nrc/客户端/src'。 'rootDir' 应包含所有源文件。

错误 TS6059:文件 '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.ts' 不在 'rootDir' '/Users/thill/Projects/nrc/客户端/src'。 'rootDir' 应包含所有源文件。

错误 TS6059:文件 '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/timepicker-event-interface.ts' 不在 'rootDir' '/Users/thill/Projects/ nrc/客户端/src'。 'rootDir' 应包含所有源文件。

@HillTravis你可以相信我 :) 这是我们对符号链接的不一致处理导致编译器关闭。 我们仅在节点模块解析时使用符号链接,然后使用该名称作为文件名; 然后我们执行检查以确保所有文件都使用真实路径而不是用户指定的路径在源目录下。 这就是产生错误的原因。

作为测试,我尝试删除符号链接。 实际上,我删除了整个build文件夹。 然后我再次运行tsc ,仍然看到错误。

在更多测试期间,我尝试注释掉该特定节点模块 (ng2-datetime) 的代码内导入和使用,并且错误消失了。 因此,只有当我尝试导入该节点模块时,我才会看到错误,而不管符号链接如何。

如果您查看 GitHub 上该包的源代码,您会看到 package.json 文件的“main”参数设置为“ng2-datetime.js”,尽管作者也发布了相同的 .ts 文件姓名。 这似乎是导致问题的原因。 如果我创建 .d.ts 文件并删除 .ts 文件,问题就会消失。 即使在重新添加符号链接后,它也没有问题。

因此,恕我直言,我不明白这个问题如何与符号链接具体相关。 当作者在包中包含 .ts 文件时,它似乎通常会导致问题。

你知道是否有任何解决方法吗? 上面的 OP 说通过将“排除”添加回 tsconfig.json 来解决它。 我已经排除了该目录,但它仍在尝试编译它。

你知道是否有任何解决方法吗? 上面的 OP 说通过将“排除”添加回 tsconfig.json 来解决它。 我已经排除了该目录,但它仍在尝试编译它。

这可能与另一个有关,但我现在找不到。 在解析类型时, tsc总是尝试从node_modules查找它,而它不存在(与typings )。

“tsc 不应该关心并因 rootDir 之外的 ts 文件而失败”我同意。

不明白为什么打字稿会在 rootDir 之外查看 JS 文件,因为所有源都应该在那里。
错误消息说“'rootDir' 应该包含所有源文件”,那么就 TS 而言,不应期望或假定该目录之外的任何内容是源文件!

如果这是“按预期工作”,那么这种行为的意图或动机究竟是什么? 是否存在 TS 想要编译位于 rootDir 之外的源文件的情况?

另一方面,在 tsconfig 中添加“include”部分可以解决问题。 当提供要包含的文件或目录时,TS 不会查看除此之外的其他文件。

使用打字稿 1.8.10

我的 homedir ~/node_modules有一个 node_modules 文件夹。 从我的项目目录~/projects/myProject/运行tsc ~/projects/myProject/导致打字稿抱怨以下文件

../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/config.d.ts(29,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(36,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(68,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(75,111): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/request.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/services/glacier.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.

非常混乱 - 虽然不知道为什么我的主目录中有一个节点模块文件夹。

@iwllyu你能不能在[email protected]上检查你的项目,如果你仍然有问题,可以提交一个新问题。

尽管 2.1.4 抱怨一组不同的文件,但它仍然存在问题

Using tsc v1.8.10
../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(27,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(34,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(66,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(73,111): error TS1110: Type expected.
Using tsc v2.1.4
../../node_modules/aws-sdk/lib/config.d.ts(38,37): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/request.d.ts(164,16): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/s3/managed_upload.d.ts(15,16): error TS2304: Cannot find name 'Promise'.

我将创建一个项目来隔离测试用例

好吧,我尝试了一个新项目,但没有发生。 由于这是一个较旧的项目,并且我已经通过删除额外的 node_modules 文件夹来修复它,因此我不会再花时间尝试重新创建它。 谢谢您的帮助!

关于本案。 如果您导入的所有类型都是来自外部的类型(就像我真的在这个“前打字稿,后打字稿”波事物上冲浪一样)-也许 tsc 可以区分我在做什么?
我只是从后端共享我的实体类型 - 到我的前端应用程序。 输出当然没有这些类的类型和导入(因为它们仅用于编译时和智能感知)。

也有这个。
Typescript 对我们的团队来说太受限制了 - 现在考虑流程。

伙计们,现在有任何解决方案吗? 在后端代码中使用来自客户端代码的类型等。

什么是最好的选择? 复制粘贴那里和那里修改,如果我改变类型?

为 2 个项目创建一个根目录不是一种选择,因为为什么后端 tsconfig.json 会包含有关 jsx 的信息并在我可以使用 es2015 时编译为 commonjs

baseUrl对你有用吗?

@unional不会改变

import * as request from "superagent";

import * as request from "node_modules/superagent/..something";

?

Bleh,这真的按预期工作吗? 我刚刚遇到了这个问题,我告诉打字稿我的源代码都在一个特定的文件夹中(通过rootDir )然后它继续_完全忽略我告诉它的内容_ 因为我碰巧有一个带有.ts文件

这真的感觉像是一个错误,如果我通过rootDir告诉编译器我的源代码在哪里,它不应该完全忽略该设置并更改我的输出文件夹结构,因为它认为我可能做错了什么。 它应该忽略不在rootDir任何文件。 或者,它应该很难失败,而不是继续发出与我想要的输出文件夹结构不符的输出!


对于任何跟随我的人,以下将做你_实际上_想要的:

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

我告诉打字稿我的源代码都在一个特定的文件夹中(通过 rootDir)

这不是rootDir意思! rootDir表示“使用此文件夹作为计算outDir路径的相对基础”。 哪些文件是您编译的一部分是一个单独的问题,由files和/或include / exclude回答

即使我接受这一点,目前的行为仍然是错误的 IMO。 如果我在指定目录之外有任何 TS 文件,那么rootDir将_not_ 成为计算outDir路径的基础,这意味着我指定的配置将被完全忽略。

我认为硬失败会好得多,因为编译器有效地认为我给出了无效的配置。 在配置无效时忽略配置是 (IMO) 不是处理此类故障的正确方法。

更清楚的示例错误消息(以及硬故障):

TSC 在 rootDir 之外找到了 typescript 文件,因此无法继续编译。 更改rootDir以包含所有打字稿文件,或排除 rootDir 之外的文件,或仅包含 rootDir 内的文件。

注意:rootDir 的当前行为感觉非常错误的很大一部分原因正是因为将文件放在 rootDir 之外是没有意义的。 当有人问自己(或编译器)编译rootDir之外的文件是什么意思时,唯一的答案是“这没有意义”。 因此,很自然地得出结论,rootDir 也指定了 sourceDir。

邪恶在于命名。 它真的意味着relativePathBaseDir或类似的东西。

我还注意到include通常的意思是“也看这里”,但在这种情况下,它的意思是“只看这里”。
我会明智地让它有另一个名字并且是强制性的。

IMO 应特别考虑此评论,以确认这确实是一个错误,应重新打开:

注意:rootDir 的当前行为感觉非常错误的很大一部分原因正是因为将文件放在 rootDir 之外是没有意义的。 当有人问自己(或编译器)编译rootDir之外的文件是什么意思时,唯一的答案是“这没有意义”。

确实,这没有意义。 “ rootDir之外的源文件”根本就不是源文件,无论它们的文件扩展名或内容如何。 编译器永远不会编译它们。 那么他为什么要抱怨他们的存在呢? 他嫉妒有档案不在他的管辖范围内吗?

+100 这是一个错误(实际上是一个令人讨厌的错误)。 考虑以下目录结构:

- src/
  - module.ts
- test/
  - module.test.ts
- out/
  - module.js

我希望tsc只编译src ,因为我用ts-node运行测试。 拥有rootDir: 'src'将导致当前编译错误。 如果您将测试和其他仅打算使用ts-node (甚至可能单独编译?)标记为“已排除”,那么糟糕的事情就会开始发生(例如vscode 突出显示在测试中被破坏

事实上, rootDirexcluded和所有其他选项的组合都不能满足所有要求(从编译中排除测试,同时仍然能够运行它们并使用它们)。

而且我真的不认为我的用例是独一无二的,所以至少从 UX 的角度重新考虑“按预期工作”标签是值得的。

src / test / out设置是项目参考解决的关键场景

我发现这个问题是因为我在谷歌上搜索为什么 typescript 在设置rootDir后试图编译我的 webpack.config.js 文件。

我告诉打字稿我的源代码都在一个特定的文件夹中(通过 rootDir)

这不是 rootDir 的意思! rootDir 的意思是“使用这个文件夹作为计算 outDir 中路径的相对基础”。 哪些文件是您编译的一部分是一个单独的问题,由文件和/或包含/排除来回答

这就是答案! rootDir 的文档

指定输入文件的根目录

我的意思是“输入 _source_ 文件”。 我建议@RyanCavanaugh的评论替换当前对此选项的解释。

在此处链接 - https://github.com/Microsoft/TypeScript/issues/11299是此问题的副本。 (解决方法:使用 include/exclude 指定要编译的文件,rootDir 不指定要编译的文件。)

@mhegazy您会在该线程上为此添加评论吗? 这似乎是提问者所指的(对为什么 TS 正在查看 RootDir 之外的任何文件感到困惑,对 rootDir 的含义同样存在误解)。

我也面临这个问题,一直无法解决。

tsc 编译正在将树从我包含的目录中移到父文件夹中,从而导致重复的类型错误。

我有一个嵌套的文件夹结构,如下所示:

└─src
└─package.json
└─node_modules
└─tsconfig.json
└─example
│ └─src
│ └─package.json
│ └─node_modules
│ └─tsconfig.json

现在,当我尝试从示例目录中运行 tsc 时,出现以下错误:

node_modules/@types/react/index.d.ts:2809:14 - error TS2300: Duplicate identifier 'LibraryManagedAttributes'.

2809         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                  ~~~~~~~~~~~~~~~~~~~~~~~~

  ../node_modules/@types/react/index.d.ts:2814:14
    2814         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                      ~~~~~~~~~~~~~~~~~~~~~~~~
    'LibraryManagedAttributes' was also declared here.

正如您在错误中看到的那样,tsc 正在沿着树向上并走出示例文件夹,并在父目录的 node_modules 文件夹中查找! 更糟糕的是,我已经尝试明确忽略父 node_modules 目录,但效果不大。

这是示例目录的 tsconfig:

{
  "compilerOptions": {
    "target": "es5",
    "experimentalDecorators": true,
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "lib": ["es2017", "dom"],
    "jsx": "react"
  }
,
  "typeRoots": [
    "./node_modules/@types"
  ],
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "../node_modules"
  ]
}

我该如何解决这个问题? 以上似乎都不适合我

@lexwebb我遇到了同样的问题,请检查yarn.lock文件中@types/react具有相同版本的文件。
请参阅https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes。

我来到这里是因为我的资产文件夹包含一个扩展名为.ts的“MPEG 传输流”视频文件,所以即使该文件夹不在我的rootDir路径中,它也会使 tsc 崩溃😄

我通过在exclude路径中添加资产文件夹来修复它,但这是一个令人不安的行为🤔

所以事实证明,我在父包和子包 json 中都有一个稍微不同的 react 版本。 匹配版本完全消除了问题。 仍然无法排除父目录表单类型检查的痛苦。

我猜这永远不会被修复。 刚刚遇到了同样的问题。 这如何“按预期工作”超出了我的范围。 我想这样做的目的是让编译器以一种荒谬的方式运行。

根据我自己的个人经验,打字稿构建从您的rootDir树中徘徊并试图构建您不期望的内容的原因是您(有意或无意地)直接或间接引用了其中的某些内容rootDir 。 如果您这样做,那么无论您是否尝试排除包含引用文件的区域,构建都将遵循参考树。 有时它可能是一个 PITA 试图找出你是如何/在哪里完成的 - 但我总是发现这是我自己的错 - 而不是tsc的错。 它只是在做我告诉它要做的事情。

每当这击中我时,都是因为类型。 我导入了一个界面或存在于文件中的东西,该文件导入了另一个文件中的其他东西,而该文件又导入了其他东西......直到最终我最终导入了位于我的rootDir之外的文件中的东西并且经常在我试图在我的配置中明确排除的东西中。

HTH 你的一些人找到了你痛苦的根源。 再多的配置也不会让你摆脱它——你只需要严格控制你的导入结构。

@kpturner这听起来非常合理,但是 - 一个没有跨文件夹导入的准系统测试项目会产生每个人都在抱怨的行为。

真的吗? 我从未见过的:)

排除的文件夹总是被排除在我所有的项目中,除非我提到的情况出现。

此线程上是否有裸骨示例? 很难从我的手机说出来。

抱歉,排斥不是我所指的“赤裸裸”情况的一部分。 我只是注意到进口似乎不是行为的原因(尽管如果是这种情况会更有意义)。

即编译这样的东西会导致错误。

-src / src.ts <- no imports -test / test.ts -out -tsconfig.json {"rootDir": "src", "outDir": "out"}

但是,如果您的tsconfig.json看起来像那样,我希望打字稿能够编译src目录中的所有内容以及test目录中的所有内容。 如果你只希望它transpile只有在东西src ,并输出到out目录,然后你的tsconfig.json必须是

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    }
}

然后它会抛出一个 TS6059 错误,因为你有一些rootDir之外的文件。 所以你必须排除那些:

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    },
    "exclude": [
        "test"
    ]
}

转换后,将生成一个名为out的文件夹,其中包含src.js子文件夹src src.jstest文件夹被完全忽略。 这就是我期望发生的 - 不是吗?

呃,事实上,我的例子tsconfig应该已经包括rootDiroutDircompilerOptions正如你在第一个例子显示。 当您排除test时,您也是正确的, test及其文件被排除在外。 最初,我以为您是说 TS6059 错误的(或)罪魁祸首是rootDir的文件从rootDir外部导入了某些内容 — 尽管我想我误读了您。 无论如何,我同意这里的其他人的看法,因为rootDir之外的目录必须按照您的描述明确排除在外。

不,我(以前)说过参考树可能会导致您排除列表中的内容被转换 - 略有不同。

TS6059 错误最初有点令人不安 - 但我认为 TS 试图帮助防止我犯错误。 如果我在定义 rootDir 时遇到了麻烦,然后 plonk 打字稿飞到了 rootDir 之外,那么 TS 实际上是在说“oi - 你创建了我无法访问的打字稿 - 是吗?”

我要么回答“不,我搞砸了是不对的”并将文件移动到 rootDir
或者
我说“是的,这是正确的,很抱歉我没有让你知道”——然后我将它添加到排除文件列表中。

这太复杂了。 我有一个 monorepo,我似乎无法找到一种方法来为自己正确编译每个包,发出正确的目录结构,同时使用paths选项导入本地包(来自同一个 monorepo)。

输出目录中的目录结构包含不需要的父文件夹,或者 tsc 抱怨文件位于根目录之外。

不会这么复杂吧?

无论我使用哪种组合中的哪个选项, tsc似乎都无法处理带有paths引用同一个 monorepo 中的本地包的 monorepo。 我试过--build , --project , references , paths , extends , rootDir , rootDirs , include , exclude , baseUrl , outDir在各种不同值的组合中,最后它抱怨文件不在rootDir或者它通过在outDir发出错误的目录结构而搞砸

我不会描述我有什么作为 monorepo,但我在同一个 repo 中有三个不同的项目 - 我可以独立地转译每个项目,而不会受到其他人的问题或干扰。 每个项目都有自己的 tsconfig

经过相当长的时间尝试和修补后,我能够获得一个带有 lerna 和 typescript 的 monorepo来运行。 打字稿配置将referencespaths结合使用,并且不再因使用rootDir而窒息。

rootDir 用于构建输出文件夹结构。 所有文件都必须在 rootDir 下,编译器才能知道在哪里写输出。

不需要任何输出的文件呢? 在 root 之外有一个 json 文件:

const errors = require("../../../../errors.json");

因为我无法编译ES6版本:

import * as errors from "../../../../errors.json";

但是,在第一个版本中,我失去了类型安全性。

@mhegazy此问题已于 3 年前关闭。 然而,它似乎在 3 年后仍然是一个混乱的根源。

您能否重新审视一下这种“按预期工作”的状态? 鉴于社区在此线程中的反应,可以肯定地说它的行为并不像社区期望的那样。 无论是文档问题、重命名该选项、更改其行为还是添加新选项,我相信实际上有一个行动项目需要您确定。

我可以理解你有比这个更高的优先级,但是在没有任何迹象表明这里给出的反馈被重视的情况下关闭这个问题并不能真正为 Typescript 传达一个很好的形象,说实话。

@ngryman我们下一步要做什么? rootDir有一个定义——这是我的源文件的公共根。 当文件不在那个公共根目录中时,根据rootDir ,这是一个错误。 该定义已记录在案。 对于人们为rootDir发明了自己的定义并随后感到惊讶这一事实,我无能为力。

这就像去星巴克并说要拿铁咖啡不应该导致得到浓缩咖啡和蒸牛奶的混合物。 这是不可操作的,因为你在争论一个定义。 如果您想要一些不同的饮料,请订购其他东西。 如果星巴克没有提供您想要的那种饮料,请提出该饮料应该是什么以及应该由什么制成的建议。

正如我在https://github.com/microsoft/TypeScript/issues/9858#issuecomment -370653478 中提到的,我认为解决这个问题的方法只是更好的错误消息。 回到当我遇到它,最终发现这个 GitHub 问题时,我最大的挫败感来自于我浪费了多少时间试图找出问题,然后认为这是一个编译器错误,然后创建了一个 repro 案例,然后发现一个重复的错误,上面写着“按预期工作”。 快速失败并显示明确的错误消息会让我省下这一切。

如果rootDir之外有源文件,则表示 TypeScript 项目配置不正确。 向用户提供一条明确的消息来表明这一点,以及如何解决它的指导,我认为这可以解决很多人的问题。

@RyanCavanaugh感谢您的快速回答。

如果我去这个页面: https :

指定输入文件的根目录。 仅用于通过 --outDir 控制输出目录结构。

我从字面上理解它“仅用于控制输出目录结构”,仅此而已。 “唯一用途”在这里很重要。 我怎么能猜到这不是编译器在现实中所做

也许我错过了一些东西,但如果是这样的话,我远不是唯一的。 因此,如果你有一个产品,而你的大量用户不了解你的产品,那么只有两条路可以走:要么你认为你的用户很愚蠢,要么你没有清楚地传达一些东西。 我希望你不要倾向于第一个😕

以星巴克的例子结束,在配料表中写上“Expresso 和蒸牛奶的混合物”,这样我就知道拿铁是什么了,我不必猜测。

rootDir之外的文件的含义是 TS 将输出outDir之外的文件,我认为这是一种不言而喻的不良行为。

错误信息可能会更好 - 我很乐意为此提出建议或 PR。

文档总是可以更好 - 再次,希望那里有关于如何更清楚地传达事物的具体想法。

暗示我说人们是愚蠢的,这不是我想要的。

rootDir 之外的文件的含义是 TS 将输出 outDir 之外的文件,我认为这是一种不言而喻的不良行为。

我仍然很不清楚为什么编译器不只是“chroot”到rootDir并且不考虑该目录之外的文件。 作为用户,可能缺乏有关tsc内部结构和历史的背景信息,这对我来说绝对不是可预测的行为。

我能想到的一个例子是 Jest,它提供了相同的选项: https: //jestjs.io/docs/en/configuration#rootdir -string。 AFAIK Jest 不考虑rootDir之外的测试文件。 例如,我希望这里有相同的行为。

文档总是可以更好 - 再次,希望那里有关于如何更清楚地传达事物的具体想法。

我很高兴您正在考虑改进这里。 @MicahZoltu的建议可能很有趣。

最后,我可以重申,我不认为rootDir是可预测的(因此人们会做出反应),但据我所知,改变该选项的行为不是值得考虑的事情。 因此,作为妥协,我还可以提议将rootDir重命名outBaseDir可能是候选对象。 但可能有一个更好的名字。

暗示我说人们是愚蠢的,这不是我想要的。

我没有暗示任何东西,如果你那样做,我很抱歉。 我只陈述了一个非常简单的事实:当用户抱怨他们不理解的东西时,实际上只有两条路可以走。 我的结论是,我希望你不要倾向于第一个。 老实说,您将自己与这些路径之一联系起来这一事实是由您自己决定的。

我想我已经说了我不得不说的话,尤其是在就如何处理此线程提供坦率的反馈方面。 所以我会给其他人留出空间来提出解决方案。

@ngryman我同意rootDir的定义和它实际做的事情似乎不一致。 当您创建一个新的 ts 项目(通过tsc --init )时, tsconfig.jsonrootDir的注释类似于您引用的/* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 。 如果我提供一个包含 _input_ 文件的目录,根据 input 的定义,我希望它甚至考虑编译的唯一文件都在该目录中。

@RyanCavanaugh在 4 年前,当 typescript用于编译成 javascript 时,报告这样的错误可能是有道理的。 我当然不想丢失文件! 但是现在随着打字稿执行的流行,比如ts-node ,似乎 tsc 对我有点嫉妒。

而在rootDir之外的打字稿文件意味着不正确的项目配置的想法是完全错误的。 我不需要将我用打字稿编写的单元测试编译为 javascript。 ts-node更快,我在编写测试时可以享受打字稿的所有好处。

我同意@CodySchrank 。 当 rootDir 中的某个源文件引用/导入它外部的文件时,TS 出错我没问题——这是意料之中的。

但是,我无法理解 TypeScript 自己查看 rootDir 之外的不相关文件并出错,而这些只是不同工具的配置文件,例如 jest 或其他什么。 我的意思是,有什么意义? 这些甚至不是我的应用程序的一部分,也没有直接在任何地方引用/导入,我的上帝,我为什么要首先将它们捆绑到生成的构建中......

我想知道将此错误转化为警告的含义是什么。 简要浏览一下代码,这似乎是可能的,但我绝对不是 tsc 构建过程的专家。 这似乎是一种让我们通知潜在问题的快乐媒介,但如果我们愿意,也可以让我们绕过它。

src / test / out设置是项目参考解决的关键场景

这至少需要每个根文件夹(https://www.typescriptlang.org/docs/handbook/project-references.html)有一个单独的项目配置。 通读了说明后,我离开时对如何实现该模式没有很好的理解,当我要求的是苍蝇拍时,我觉得我被递了一个手提钻。

当然,在我的源文件夹中将附属模块作为单独的子项目维护会更有效率,但我没有在这里编译 lodash。 我想要的是在一个公共项目文件夹下包含许多文件,例如测试和基准文件,用于静态分析,并且在编译时只发出一个目录供外界使用。 这似乎很容易指定,我正在努力理解为什么它不仅对用户来说很难做到,而且从 TS 规范的角度来看显然是 _verboten_。

我想强调的是,不允许使用此功能的唯一原因是编译器假设开发人员的意图是腐败的。 当开发人员将"outDir"./src并且编译器在./test找到一个 TS 文件时,它_可以_假设不需要发出这个文件(当然假设它没有从“outDir”中的任何文件中引用)。

但事实并非如此。 它假定开发人员_想要_发出此文件,并且由于无能或恶意指定了一个不包含它的子目录。 换句话说,编译器有机会将开发人员的指令与常见且合理的用例进行匹配,而将其与一些荒谬的东西进行匹配并拒绝继续。

就目前而言,我什至看不到"outDir"的合法用例是什么。 我假设它支持一个项目结构,其中tsconfig.json与其他配置和元数据文件位于顶层,并且所有者希望编译的文件夹仅代表嵌套在其中的源文件夹。 (只要确保这些元文件都没有以.ts结尾:那太荒谬了。)

在我看来,规范的设计是用户对抗的。 尽管菜单上列出了成分,但有人提到在星巴克订购饮料,但当它不是您所期望的时会感到沮丧。 就其本身而言,这是恰当的,但我更愿意将此功能比作不卖热狗的热狗摊。

当然,被激怒的顾客应该回头看到那个大胆地宣称热狗摊不卖热狗的大牌子。 但随着混乱的积累,热狗摊的所有者可能有机会反思他们如何向客户传达其产品的功能。

嗯,考虑到这一点,我想知道核心团队是否存在某种不变量导致这个问题:

必须编译所有源代码。 如果未编译,则不是源代码。

在用户领域,需要以某种方式解决这个问题。 我不知道我们是否通过扩展源代码的定义来做到这一点。 TypeScript,或者通过创建第二个类别(“支持代码”、“验证代码”、“外围代码”...)。 这将是预期在与源代码相同的类型定义下运行的代码,并且必须成功验证源代码才能被认为是正确的,但它不是程序与其接口相关的实际功能的一部分。

作为 TypeScript 的使用者,我对实现这样一个类别的具体困难缺乏了解。 但是,它似乎适合"outDir""outDir"内的任何内容都是源代码的一部分,它之外但项目文件夹内的任何内容都是支持代码的一部分。 使这个有用/必要的主要因素是 ts-node 的出现,这意味着我可以将这个支持代码作为一个单独的步骤来执行,完全独立于编译; 当然,我希望能够利用这一点。

未隐式包含提供给该工具的任何输入文件

这个问题是由_because_ 用户隐式地试图编译rootDir之外的文件引起的。 您基本上告诉编译器,“仅编译此目录中的文件”,然后您继续引用该目录之外的文件。 编译器很困惑,不知道如何继续。


/project/source/index.ts

import '../external.ts'

/project/tsconfig.json

{
  "compilerOptions": {
    "rootDir": "./source"
  }
}

在这个例子中,你告诉编译器“源文件只在‘源’目录中”。 然后这些文件之一引用了源目录中_not_ 的文件。 TypeScript 现在有两个相互冲突的指令,一个说只编译源目录中的文件,另一个说编译源目录外的文件。

@MattiasMartens您隐含地将includerootDir混为一谈。 如果你有/src/test ,如果includesrc/*那么你就不会得到关于/test东西的错误,除非来自src错误地从test导入了一些东西,您应该对此感到高兴!

提供一种机制来写下程序中不正确的导入是什么样的,并在发生这种不正确的导入时发出错误,这不是用户敌对或敌对的。 我再次认为这是来自对标志含义的误解 - 它们主要是选择加入强制检查,以帮助您验证您的程序是否配置正确。


反正!

鉴于rootDir的定义,当 TypeScript 在提供的rootDir之外看到文件时,它有一些选项:

  • outDir上方发出一个文件(假设这是可能的!),这与用户关于输出位置的说明相矛盾
  • 处理文件但不发出它,如果没有其他构建步骤将产生一个非工作程序
  • 由于项目似乎配置错​​误而发出错误

我强烈反对发出非工作程序应该是默认值的概念。 如果这里的功能请求只是将rootDir之外的.ts文件视为.d.ts ,这是合理的,它只是与rootDir意思除了rootDir 。 你会怎么称呼这样的旗帜?

@MattiasMartens您隐含地将includerootDir混为一谈。 如果你有/src/test ,如果includesrc/*那么你就不会得到关于/test东西的错误,除非来自src错误地从test导入了一些东西,您应该对此感到高兴!

确实如此。 我对include ,发现它在这种情况下的效果比我想象的要好,包括使用 VSCode 的工具。

我仍然希望在编译时验证但不在编译时发出的代码,这是include不包括的内容。 但这是一个单独的请求,无需在此讨论。

我认为这是来自对标志_mean_ 的误解的地方 - 它们主要是 _opt-in 强制检查_ 以帮助您验证您的程序是否正确配置。

我对此感到困惑。 您认为rootDir是一种选择加入的强制检查吗? 它会影响最终发出的内容,因此它显然不是 _only_ 强制检查。

一些标志,如target ,会彻底改变将发出的内容——它们不是强制检查,而是编译器指令。 rootDir读起来就像编译器指令,并且被记录下来。

我强烈反对 _emit a non-working program_ 应该是默认值的观点。

从我到目前为止读到的这个帖子来看,似乎有一个广泛的共识,即从rootDir内的文件rootDir外的文件rootDir之外的项目文件夹中找到任何 TS 文件,是否是rootDir的文件,则会引发错误

值得重复一遍:我将rootDir设置rootDir内容无关,然后它停止了! 这种特定行为并不能帮助我理解我的代码。 这很烦人。

确实,从rootDir的 TypeScript 定义的角度来看,正如本线程中所阐述的那样,这种行为是完全合理的,每个来这里表达不满的人都是错误的。 但从传统的、预期的根目录定义来看,这是不合理的。 我告诉你,在我提供根目录的几乎任何上下文中,我是在告诉程序从哪里开始遍历文件结构,而不是询问它是否绝对确定文件系统中没有其他东西我也可能是有兴趣。

定义可能是错误的。 它们是可以改变的。 为了向后兼容,不需要保留定义,只需要保留功能。

如果这里的功能请求只是将.ts之外的rootDir .ts文件视为.d.ts

我...不认为我想要那个,原因几乎与我希望编译器在rootDir某些内容从外部导入代码时抛出错误的原因相同。 我确实认为rootDir的内容(如果我提供的话)应该从周围的代码中进行封装。

我认为避免我和其他人不想要的行为的最简单方法是隐式排除rootDir的文件,如果rootDir的文件不引用它们。 如果rootDir确实引用了它们,则应该抛出错误,就像当前一样。

每个段落似乎都归结为“ rootDir应该更改include的默认值”,如果我们今天同时添加这些标志,这将是一个合理的建议,但是不是我们此时可以进行的破坏性更改。 尽管可以说让所有配置标志相互交互更多地增加了认知负荷,而不是减少了它。

也许我们应该在include未明确设置并且包含的​​文件在rootDir之外时发出自定义错误。

文件“tests/foo.ts”在 rootDir 'src' 之外。 您是否忘记设置“包含”模式?

记录 #33515

我有这个问题,以及在https://github.com/microsoft/TypeScript/issues/31757#event -2480427393

rootDir、include 和 exclude 之间的相互作用设计得非常奇怪。

我一直认为 rootDir 是编译器开始遍历的文件夹,包括可能从 rootDir 引用的其他文件夹(例如供应商文件夹)。

当前的定义非常奇怪,而且非常不直观。

具有讽刺意味的是,令人困惑的是它们相互作用:这些设置根本不会相互影响。 include 100% 控制程序中的内容, rootDir 100% 控制计算outDir的布局。

只是添加另一个问题示例,这是我的文件夹结构:

tsconfig.json
package.json
src/index.ts

我的 tsconfig 中有:

"rootDir": "src",
"outDir": "lib",

在我的“index.ts”(src 文件夹)中

import pkg from '../package.json'; // I read the package.json object

export class SomeClass {
  public version = pkg.version;
}

我_知道_在构建之后,“index.js”文件将位于“lib”文件夹中。 而且我_知道_ package.json 将升级 1 级。
我不认为 Typescript 应该比我更了解我的文件夹结构并破坏构建。 它应该简单地记录有关 rootDir 文件夹之外的一些文件的警告,这些文件未包含在输出文件夹中。

@sebelga我可能会认为这是一个错误 - 允许.json来自rootDir外部是可以的,因为 TS 不会将其复制到输出文件夹

@sebelga我可能会认为这是一个错误 - 允许来自 rootDir 外部的 .json 没问题,因为 TS 不会将其复制到输出文件夹

谢谢,不是真的......我们有一些特殊的规则来发出 .json 文件......如果文件将在其自身的同一位置发出,那么只有它不会发出。 在所有情况下它都会被发出(例如,当指定 --outDir 时,它将被发出到该文件夹​​中)

@RyanCavanaugh我有一个类似用途的情况下@sebelga我想要的console.log出的版本号从package.json在运行时。

所以我的解决方案是改变我的"rootDir": "." ,然后我有这包括

"include": [
    "src",
    "typings"
  ]

由于package.json文件包含在lib (built) 文件夹中,其中包含一个“src”子文件夹,因此我编写了一个 bash 脚本,该脚本在构建后立即运行以清理内容。

#!/bin/bash

rm lib/package.json
mv $(pwd)/lib/src/* $(pwd)/lib
rm -rf lib/src

它确实有效,但对我来说感觉很糟糕。

@sebelga您在typings文件夹中有.ts文件吗? 如果没有,将rootDirsrc并跳过脚本是合法的。

@sebelga而不是const { version } require('../../package.json')import { version } from 'package.json') ,您是否尝试过这样做:

import { sync as loadJsonFileSync } from 'load-json-file';

const { version } = loadJsonFileSync('../../package.json');

打字稿不会关心它rootDir这种方式在

https://github.com/sindresorhus/load-json-file

如果你想避免硬编码所有的../..你可以试试这个:
https://github.com/sindresorhus/read-pkg-up

@RyanCavanaugh 如上所述,我无法将其设置为“src”。 我正在我们的 src ( import pkg from '../package.json'; ) 之外导入“package.json”,而 tsc 不允许这样做。

感谢分享这个@dylang ! 我会尝试。

我告诉打字稿我的源代码都在一个特定的文件夹中(通过 rootDir)

这不是rootDir意思! rootDir表示“使用此文件夹作为计算outDir路径的相对基础”。 _哪些文件是您编译的一部分_ 是一个单独的问题,由files和/或include / exclude回答

@RyanCavanaugh但它是什么rootDir应该是说,这就是这个问题的。

当我看到自 2016 年以来一直存在的问题时,我不太擅长保持镇定,这些问题可能会通过引入新的“compilerOption”来让编译器知道它可以忽略错误而在不为现有用户引入新问题的情况下非常固定在给定的用例中。

为此,我深表歉意。 我无法帮助它,因为我依赖于提供良好的服务,但我偶尔会遇到这样的问题线程。 为什么 TypeScript 的作者很难实现一个简单的配置标志?

我不认为这是因为开发人员懒惰,或者因为他们不愿意提供帮助。 我不认为这里的任何人都是坏人,除了我自己。

正是这场冲突,这场争论,已经持续了多年,似乎是关于属性“rootDir”的定义。 以及如何处理这个问题。

人们被卷入这场辩论是因为他们相信自己是对的。 是的,“rootDir”用作源代码的基本目录。 是的,错误是有效的。

然而,根本问题仍然存在。 我的工具完美地编译了代码,但我的 IDE 在我的屏幕上显示了这个错误。 这是一个变态。 我想要那些红线消失。 我的文件中没有错误。 如果他们这样做,我应该专注于那些,而不是被这些非问题分心。

我想要的只是抑制此错误消息。 我想这就是我们大多数人想要的。 我不知道这里是否还有其他案例,也许有人愿意就此发表意见。

我们可以一起努力解决这个问题吗? 看到那些红线消失了,我会很高兴……

@nullquery如果tsc有效,但您的 IDE 显示红色波浪线,则表示您的 IDE 使用的编译器版本或配置与tsc

@nullquery提交一个错误,显示如何重现问题,我们将修复它或告诉您项目配置有什么问题

@sebelga解决方法之后,这里有一个变体,适用于您的 npm 脚本

tsc --module commonjs --target ESNext --outDir ./edition-esnext --project tsconfig.json && test -d edition-esnext/source && ( mv edition-esnext/source edition-temp && rm -Rf edition-esnext && mv edition-temp edition-esnext ) || true

示例用法在这里。

Boundation 会自动为您应用它。

解决方案是Project References

要使用它,请编辑“tsconfig.json”文件并将其添加到文件末尾(在“compilerOptions”之外):

"references": [
    { "path": "../common" }
]

这将允许您引用“../common/”文件夹(以及所有子文件夹)中的文件。


我之前的困惑源于这样一个事实,即尽管使用相同的“tsconfig.json”文件,IntelliJ 和我未受污染的gulp-typescript任务给了我不同的结果。

事实证明,出于某种原因,“gulp-typescript”正在尝试一种尽力而为的编译方法。

TypeScript 中的错误(例如let z: number = '' )将在 IntelliJ 中被标记,但“gulp-typescript”编译它就好了。
“gulp-typescript”仅标记 JavaScript 语法错误(例如let 1z = '' )。

因此,如果您是“gulp-typescript”用户,根据您的“gulp-typescript”版本和配置,您可能会遇到这样的问题。 (在撰写本文时,我使用的是最新版本,但我假设未来的某个人可能会阅读此内容。我希望时间对您更好。)


我知道 Project References 的使用被埋没在大量的响应中,但如果能更好地记录下来会更好。

Google 上“TS6059”的前 3 个结果都导致了 GitHub 问题。 如果有一个页面记录这些常见错误及其解决方案,我会更清楚。

@MicahZoltu这是可以解决的问题吗? 我应该提出一个新问题,还是如果在主要贡献者之间进行内部讨论会更快?

(FWIW 我不是 TypeScript 团队的一员)

通常,我建议不要使用path s,除非您绝对必须这样做。 我相信它的目的是允许与具有奇怪依赖结构的遗留 JS 项目兼容,但我不相信它打算用于任何新项目,如果你发现自己需要它,你可能想考虑迁移它时你有机会。 我不亲自使用它,所以我无法真正帮助解决您可能遇到的问题,但是我看到很多人都在为它而苦苦挣扎,解决方案通常是“停止使用它”。

至于 gulp-typescript,听起来 gulp-typescript 使用的 TSC 版本可能与 IntelliJ 使用的 TSC 版本不同。 当您看到您描述的症状时,这通常是问题所在(另一个是他们没有使用相同的tsconfig.json )。

"gulp-typescript" 使用的版本应该是相同的; 两个版本都源自node_modules 。 我尝试了各种方法来捕获错误并修改与之相关的设置(包括弄乱“gulp-typescript”提供的各种“报告者”并尝试覆盖设置以发出更多错误。似乎没有任何效果。

不过没关系。 只要 IntelliJ 给我错误,我很高兴接受 Gulp 任务会忽略它们。


我不喜欢修改我的方法以支持本周的首选方法。 我拥有的项目结构对我来说很有意义。 它保留了所有内容,但让我可以灵活地将内容分成多个组件。

我不相信“出于遗留原因允许兼容性”,尤其是在项目引用方面。 _必须_ 可以引用rootDir之外的文件,否则您将无法自由地以对您和您的团队有意义的方式定义项目结构。


当我第一次开始使用 TypeScript 时,我遇到了很多问题。 他们之中:

  • 对于包含 JavaScript 文件,当时的首选解决方案似乎是 AMD。 该网站听起来很官方,网上有很多 AMD 生产使用的例子。 但显然,Webpack 是新的大事,所以有些项目根本无法在 AMD 环境中运行。 经验教训:不是每个人都会采用新方法,所以你总是被搞砸了。

  • 我不清楚从 TypeScript 到最终缩小的 JavaScript(带有源映射)的道路。 当时有几种不同的方法可用,但当时它们似乎都不能与“tsconfig.json”文件和/或我的 IDE 一起使用。 经验教训:如果你想把事情做好,你必须自己做; 不要依赖其他人为您完成工作,无论他们多么善意,没有人是完美的,也没有人可以预测_您的_工作空间。

  • 我想要一个自定义的东西:一种将 HTML 文件的内容转换为 JavaScript 字典以供包含的方法。 这本应该是我唯一的绊脚石,但最终,这变成了更容易编写的脚本之一。

我最终不得不开发自己的 Gulpfile 来处理所有事情。 它执行以下操作:

  • 将用于分发的缩小的 JavaScript 文件从node_modules文件夹复制到我的 webroot。 这听起来很简单,但我尝试包含的几乎每个 JavaScript 库都有一个不同的地方来存储它们缩小的 JavaScript 文件。 没有配置,没有明确的文件路径。 我最终不得不为我想要包含的每个 JavaScript 库编写单独的脚本。 它可以工作,假设位置在未来版本中不会改变,但如果是这样,我总是可以更改复制脚本。

  • 根据本地“tsconfig.json”文件编译 TypeScript,该文件在输出目录中生成单独的文件(使用outDir ),因此我可以确定 TypeScript 在我的 IDE 中的编译方式与在 Gulp 中的编译方式相同(哈哈哈!),然后使用“rollup”插件将这些文件压缩成一个 JavaScript 文件,然后运行 ​​UglifyJS 来缩小这个文件,同时维护一个映射回原始 TypeScript 文件的源映射。

  • (自定义任务)为 TypeScript 源根目录中的每个 HTML 文件生成一个包含名为html_templates的字典的 JavaScript 文件,并将其作为缩小的 JavaScript 文件放置在我的 webroot 文件夹中。

可能有更优雅的方法,但是在从一个开源项目跳到下一个之后,我已经在每个人提供的解决方案之间进行了足够的折衷。

我选择的方法行之有效,它很容易理解(尤其是现在我知道“gulp-typescript”做了一些不同的事情)并且我可能会在未来几年继续使用它。

最好的解决方案是您自己了解的解决方案。 虽然这对任何试图帮助我的人没有帮助(我非常感谢!我的意思是帮助,而不是混乱)我可以从经验中说_any_解决方案总是有问题,所以最好坚持一些东西你拥有自己而不是由不同信仰、性取向和性别认同的多元文化团队设计、开发和生产的东西。


tl;dr 请不要破坏项目引用。 我需要它让我的工具工作。 谢谢你

我放弃了预先设置多项目 TS 设置,只在每个项目中执行tsc -wnpm link ,然后您就可以忽略多项目 tsconfig 的所有复杂性,只需参考其他项目就像node_modules的普通 node.js 依赖项。

但是今天在一个项目中,我将目标从es5更改es6并且它不再编译,因为File '.../lib.ts' is not under 'rootDir'

文件结构:

/app
 - tsconfig.json // rootDir = "."
 - app.ts (

/app/node_modules/lib
 - tsconfig.json // rootDir = "."
 - lib.ts
 - lib.js
 - lib.d.ts

为什么tsc中的/app关心/app/node_modules/lib/lib.ts文件? 它根本不应该使用该文件。 已编译/app/node_modules/lib/lib.js/app/node_modules/lib/lib.d.ts

如果/app/node_modules/lib/lib.ts被删除 -令人惊讶 - 它编译得很好。

@alexeypetrushin你可以看看我的一些项目。 它似乎工作正常。 例如:

import * as pkg from '../package.json';

不。 我无法找到关闭此错误的方法。

@SephReed :我在 StackOverflow 上花费了 200 个代表点,有人贡献了这个非常简单的导入../package.json解决方案所有你需要做的是放置typings.d.ts文件在同一目录下的package.json ,与此内容:

declare module '*.json';

我不知道这是如何工作的,但老实说,我不在乎。 在那个阶段,TS 是为自己分叉,而不是为我分叉。

我很惊讶这是一场如此激烈的辩论。 但我明白其中的道理。 对我来说,我当然有源文件夹,但我也在该文件夹之外构建了脚本,这些脚本不打算编译但肯定包含类型支持,因为老实说,您最好的 IntelliSense 是 TypeScript。

repo/
⊢ config/  << provide TS support, but don't build this directory
  ⨽ webpack.config.ts 
⊢ scripts/  << provide TS support, but don't build this directory
  ⨽ release.ts
⊢ src/        << build this directory
  ⨽ example.ts
⨽ tsconfig.json

所以我使用"rootDir": "src"来确保文件被定向到dist而不是dist/src 。 但是当然,TypeScript 喜欢抱怨这种设置,但是由于我使用 Webpack,所以它不会为我出错。

我终于明白了这个标志的确切含义,没有几条评论让我更清楚。 只是为此欢呼。

为 tsc 设置文件夹和文件以考虑编译的选项:“文件”、“包含”、“排除”。

那你用“rootDir”做什么?
rootDir 是源文件的目录结构(层次结构)的根目录,tsc 使用它来发出相同的目录结构,从 tsconfig.json 目录或“outDir”(如果已指定)开始。 所以这不是 tsc 用作“outDir”基本路径的路径。 “outDir”只是 tsc 发出输出文件的根。
例如,假设您的 java 项目具有此目录结构。

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

当您如下设置“include”和“rootDir”时,tsc 将生成如下输出:

"include": "src/main/resources/static/ts" *
"rootDir": "." *

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.js *
          test.ts

当您还将“outDir”设置为如下时,tsc 将生成如下输出:

"include": "src/main/resources/static/ts"
"rootDir": "."
"outDir": "build" *

- build
  - src
    - main
      - resources
        - static
          - ts
            test.js *
- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

可能您想通过设置“rootDir”选项并更改“outDir”选项来实现这一点,如下所示。

"include": "src/main/resources/static/ts"
"rootDir": "src/main/resources/static/ts" *
"outDir": "src/main/resources/static/js" *

- src
  - main
    - java
    - resources
      - static
        - js
          test.js *
        - ts
          test.ts

因此,当您设置的“rootDir”选项不包括“排除”选项之外的文件范围时,tsc 将无法构建,因为它对“rootDir”选项的目的没有意义。

是的,这完全是一种糟糕的命名习惯。 它应该只是“rootOfStructureOfInputs”之类的。 而且,“outDir”应该只是“rootOfOutputs”。

您在 SS 上看到的不是 WebStorm 问题 - 它来自 TS DevServer。
第二个推荐的进口是废话。 它从“通信”源文件夹中提取。 我不知道谁他妈的应该想要那个。 使用这样的导入编译文件会产生一系列问题。

我也试过:

"exclude": ["lib", "node_modules",
        "..", "../..", "../../..", "../../../..", "../../../../..", "../../../../../.."
    ]

也没有解决问题

Bildschirmfoto 2020-07-22 um 10 08 28

@mhegazy您将此问题标记为“按预期工作”,但事实并非如此。 正如您在我的屏幕截图中看到的,tsc-server 提供了我的 rootDir(在本例中为 mobiservice/src)之外的文件作为导入建议。 对我来说,这看起来像是一个错误......

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

Antony-Jones picture Antony-Jones  ·  3评论

remojansen picture remojansen  ·  3评论

weswigham picture weswigham  ·  3评论

MartynasZilinskas picture MartynasZilinskas  ·  3评论

jbondc picture jbondc  ·  3评论