Rollup-plugin-typescript2: 原始tsconfig.json中的索引会覆盖默认的tsconfig选项“ include”

创建于 2020-05-07  ·  24评论  ·  资料来源: ezolenko/rollup-plugin-typescript2

会发生什么,为什么会出错

该错误确实很奇怪。
在某个时候,我开始收到由include typescript2 config的include选项和项目tsconfig.json引起的怪异错误。
我什至不再了解它是如何工作的,它是覆盖还是连接或是什么?
然后,我决定需要调试该数组以检查最终到达的数组

我的rollup-plugin-typescript2配置:

  typescript2({
      clean: true,
      tsconfigDefaults: {
        ....
        include: [path.resolve(__dirname, 'styles.d.ts')],
      }
    }),

我的tsconfig.json配置:

   ...
  "include": ["src", "declaration.d.ts"]
}

结果是
Screenshot 2020-05-07 at 19 44 57

正如我之前所说,我开始调试它,每次都会给您带来一些尴尬的结果。
实际上,它并没有连接这些属性,而是替换了索引单元中的值,这简直令人惊讶,并且恶化了开发人员的经验。

我的意思是说:
它将我的tsconfig数组的索引取0并将其放在typescript2 config的0索引下。

范例1:

typescript2: ['a']
tsconfig: ['b', 'c']
result: ['b', 'c']

范例2:

typescript2: ['a', 'd']
tsconfig: ['b', 'c']
result: ['b', 'c']

范例3:

typescript2: ['a', 'd', 'e']
tsconfig: ['b', 'c']
result: ['b', 'c', 'e']

太烦人了

环境

我不确定这是否相关,但是
节点:13.13.0
作业系统:macOS Catalina 10.15.4

版本号

  • 打字稿:3.8.3
  • 汇总:2.8.1
  • 汇总插件类型脚本2:0.27.0

最有用的评论

我认为无论我们在这里做什么,都必须打破常规。 为了使其按照文档和属性名称的精神行事,基本上应该这样做:

  • tsconfigDefaults -这是下面所有内容都将被深深合并的对象
  • tsconfig -这是我们从打字稿中获取的对象,包括它自己的导入内容和所有内容。 此处的所有值替换tsconfigDefaults 。 此处的所有数组都与tsconfigDefaults数组连接在一起。
  • tsconfigOverride -这是核选项。 对象仍然被深深地合并,但是这里的数组代替了批发的数组。 因此,如果您在此处提供一个空的包含数组,则最终tsconfig根本不会包含任何包含。

是否可以涵盖我们要支持的所有情况(在用户进行适当更改后),还是我遗漏了一些东西?

所有24条评论

这使使用include不可能,因为您永远不知道tsconfig.json的数组将有多长时间

有趣的是,
如果我将typescript2 config include选项从tsconfigDefaults移到tsconfigOverride
它将按索引覆盖原始的tsconfig.json include选项。

也就是说,恰恰相反
但这也很糟糕

还有一件事
经过一些额外的调查
我意识到相同的行为也与其他数组属性相关

所以我之前在https://github.com/jaredpalmer/tsdx/pull/666#discussion_r404847759中遇到了这个问题,对于每个问题,这就是_.merge的深度合并的工作方式。 这是一次深度合并,因此它将合并数组,而索引是数组的唯一标识符。 可能是_unexpected_,但它是深度合并,这就是深度合并的工作方式。

实际上,它不会连接这些属性,而是替换索引单元格中的值

  • 取而代之的是做一个添加/合并根本不会合并,也根本不会用tsconfig覆盖。 对我来说,这似乎是错误的行为。
  • 取而代之的是进行浅层合并只会覆盖默认值,我也不敢肯定这是预期的行为,但这类似于tsconfig对于exclude :如果添加一个exclude ,它将覆盖默认值。

我可以编写PR来对includeexclude进行浅层合并,但这将_pretty_破坏了更改; 我不知道这将如何影响所有下游用户。 如果TSDX用户期望浅合并或深合并,则为Idk,但是如果期望深合并,则将破坏其用法。

如果我将typescript2 config include选项从tsconfigDefaults移到tsconfigOverride
它将按索引覆盖原始的tsconfig.json include选项。

也就是说,恰恰相反

是的,这就是tsconfigOverride工作方式,它是一个替代。

我意识到相同的行为也与其他数组属性相关

是的,这就是_.merge进行深度合并的方式,因此tsconfig中的任何数组都具有相同的更改。

@ agilgur5感谢您的回复!

1)从我的角度来看,此行为使配置完全无用。 如果我们绑定到阵列中的某个位置,我们将无法保证配置的可靠性。

2)确实,这将是一个重大突破。 但是,如果我们的方向是获得最佳DX ,那么我们应该使这件事变得清楚和有用。

我口袋里有个技巧来处理这个问题,但是从干净的代码角度来看,它看起来很嘈杂-只需阅读tsconfig ,获取include属性并将其与我的数组连接即可。 看起来应该更简单。

我的建议:
1)默认-收集默认属性并与原始tsconfig连接; 删除重复项。
2)覆盖-仅应用覆盖选项

缺省值通常在被覆盖时不会串联,它们会被覆盖。 正如我上面提到的,串联使_impossible_可以使用tsconfig覆盖默认值。 对于我来说,这听起来是错误的,有多种方式,所以我强烈建议不要这样做。

我认为所有选项都令人困惑,我不确定我是否同意其中任何一个都是“最佳DX”。 浅表合并是tsconfig与默认值exclude一起工作的最接近的方法,但这并非没有取舍。
通常,需要对重大变化进行很多思考,这就是我提出这一点的原因-下游影响不小。 TSDX还必须发布重大更改以更新为此类更改。

@ agilgur5很好,那么我完全不能使用默认值或替代值。
原因? 无法保证不会在该索引上写入任何值。
另外,您可以通过undefined作为数组的值来解决所有问题,并进一步添加所需的值。 事实证明,该系统存在差距吗? 太好了

案子:

  1. 我想在“ include”配置属性中添加其他类型的d.ts
  2. 用户将他的src目录放在“ include”内,并在src之外键入另一个项目特定的d.ts src
  1. ['config.d.ts`]
    2。['src','some.d.ts','another.d.ts']
  2. 结果:['src','some.d.ts','another.d.ts']

如您所见,无法正确配置它。 我应该阅读tsconfig.json,获取其“ include”属性并将其合并到['src','some.d.ts','another.d.ts','config.d.ts']中。
我认为这是一个完整的开销。

同时,我弄清楚了问题所在。 其他人可能没有弄清楚,而是花了宝贵的时间来找出对他们不起作用的东西。
在您的第一条信息之后,我已经至少看到了2个相关问题。 而且它将继续下去。

我看到它是因为,如果我们保留一切,那么我将无法使用它,对我来说这是一个黑匣子,因为我无法保证任何事情。
没有个人喜好“喜欢” /“不喜欢”的空间。
可以使用或不使用。 而且不可能。

我毫不犹豫地收集了参与其中的其他人的意见。
还有一件事,对于当前的解决方案,我没有任何问题,我拥有上述的hack,可以随时使用。 但是我不理解使该解决方案透明化会带来什么问题,而又与必须进行重大更改这一事实无关。

我的意思是,您已经在这里给出了自己的喜好,而我已经给出了多个不同的选择。 我已经说过两次了,为什么从根本上打破了这种偏好(串联),同样没有直觉,而根本没有“透明”。 再说一遍,串联并不是一个重大的改变,它实际上使不可能的事情不可能
事实是,不可能用连接覆盖不是“首选项”。

同样,不能覆盖的“默认”也不是默认,这是必要条件。 将“默认”更改为要求没有意义,并且是错误的行为。

您现在可以覆盖深度合并,不能覆盖串联。 使现有用例不可能是没有道理的。

我也已经两次给出了一个从根本上没有破坏的替代选项,这是一个浅层的合并。 我将再次重复,您也可以使用浅表合并来解决此问题。
这是否更好还有待商.。 一切都需要权衡。

我之前在这里做出了修复错误的贡献(我知道这是_.merge因为我已经阅读了代码库),并且我维护的库在该库的使用中占了很大一部分(〜10%),我是不只是在这里说要说...

更不用说,这可以在不中断更改的情况下解决-您可以为tsconfigConcattsconfigDefaultShallow等添加新选项。

说只有一种选择,它必须打破并且必须使现有用例成为不可能,这是完全不正确的。

我认为无论我们在这里做什么,都必须打破常规。 为了使其按照文档和属性名称的精神行事,基本上应该这样做:

  • tsconfigDefaults -这是下面所有内容都将被深深合并的对象
  • tsconfig -这是我们从打字稿中获取的对象,包括它自己的导入内容和所有内容。 此处的所有值替换tsconfigDefaults 。 此处的所有数组都与tsconfigDefaults数组连接在一起。
  • tsconfigOverride -这是核选项。 对象仍然被深深地合并,但是这里的数组代替了批发的数组。 因此,如果您在此处提供一个空的包含数组,则最终tsconfig根本不会包含任何包含。

是否可以涵盖我们要支持的所有情况(在用户进行适当更改后),还是我遗漏了一些东西?

@ezolenko听起来很棒,使用起来很有道理

@ezolenko我不确定你为什么要打破事情? 我已经给出了不间断的选项。

我不确定您列出的内容如何反映“文档和属性名称的精神”,因为文档说:

传递为tsconfigDefaults将与加载的tsconfig.json合并。 传递给打字稿的最终配置将是tsconfigDefaults的值的结果,该值将替换为已加载的tsconfig.json
[...]
这是一个深刻的合并(对象合并,阵列连接在一起,图元被替换等),增加verbosity 3,寻找parsed tsconfig如果你得到意想不到的事情。

它说“合并”,“已替换”和“深度合并”,所有这些都意味着替换和覆盖默认值。 与“其余”有一个单独的引用,“引用”与rest_有所不同,但深度合并实际上不会并置。 5位引用者说了一件事,而第六位则说错了。 对我来说,这听起来像是错误的第6个参考,应该纠正,而不是将5个正确的参考更改为不正确的第6个参考。

lodash是事实上的标准,它对merge的定义是_not_不能连接。 默认值的定义是,当您设置相同的属性值_not_并置时,它们将被覆盖:

_.defaults({ a: ['a'] }, { a: ['b', 'c'] });
// => {a: ['a']}
_.defaultsDeep({ a: ['a'] }, { a: ['b', 'c'] });
// => {a: ['a', 'c']}

如果您想添加一个串联选项,我认为这应该是一个单独的配置,因为它也与文档中的5个以上引用都不匹配,并且这根本不是默认值的含义,无论在定义上还是在任何用法上均不如此。图书馆。

它还使用tsconfigOverride以及它自己的文档打破了对称性:

  • tsconfigOverride{}
    参见tsconfigDefaults

我希望默认值会被覆盖,即定义,使它们串联起来是难以理解的。 深度合并对于数组可能并不直观,但是文档明确表示这是深度合并,由于索引是相关的,因此我很快就知道这是问题所在。 我也没有报告错误,因为这就是文档所说的,甚至链接到深度合并-这是预期的行为,而不是错误。

正如我说过的,浅合并数组可能更直观,因为这就是tsconfig _itself_实际的工作方式。 正如我上面所链接的,当您添加exclude时, tsconfig _itself_不会并置,它会覆盖现有的exclude

因此,串联已不匹配文档中的5个以上引用,合并的定义,默认值的定义或tsconfig自己的行为。 并且它破坏了对称性和其他选项的文档。 我不确定这是如何直观的。

正如我多次说过的那样,使其成为非常不直观的连接而不是覆盖使某些用例_impossible_成为

https://github.com/jaredpalmer/tsdx/blob/17ffcd215f78a4e9d6936644cbeab332f6439088/src/createRollupConfig.ts#L149 -L178

目的是,如果您添加自己的exclude ,它将覆盖我们设置的默认值。 仅在未设置属性名称的情况下才应用默认值,就像其他所有属性名称一样(同样,这是默认值的定义以及默认值在所有库中的工作方式)。

如果您要将其更改为连接,那么用户现在无法覆盖我们的默认exclude ,这是_impossible_ ,他们可以覆盖默认值。 我们还提供了tsconfig的默认exclude ,因此即使tsconfig _itself_可以让您做到这一点,也_impossible_可以覆盖tsconfig的默认值那。

不知道为什么我要在整个生态系统_中重复_现有定义_和_现有用法_时,像破记录一样说话。

@ agilgur5

正如我多次说过的那样,使其成为非常不直观的连接,而不是覆盖
使得某些用例不可能实现。 这是TSDX的用法:
https://github.com/jaredpalmer/tsdx/blob/17ffcd215f78a4e9d6936644cbeab332f6439088/src/createRollupConfig.ts#L149 -L178

这种配置很容易被破坏,我不明白为什么这对您不明显。 我不希望我的库脆弱,这就是为什么创建此问题的原因。

有趣的是, @ ezolenko和我已经提出了一种可以保护包括TSDX在内的解决方案,但是您仍然会抵制。

仅在未设置属性名称的情况下才应用默认值

我同意默认行为。 仅当tsconfig没有相应的属性时才应用config default是有意义的,但这会引起许多其他更复杂的问题,其解决方案将使API变得过于复杂。

他们无法覆盖默认值

问题是,用户为什么应该有权访问图书馆作者禁止的内容?

我们必须具有无法覆盖的tsconfig配置,但与此同时,我们需要有机会对预设进行扩展。 这是重点。

解决方案仅在于新API的设计。

这种配置很容易被破坏,我不明白为什么这对您不明显。 我不希望我的库脆弱,这就是为什么创建此问题的原因。

您是从我口中说出我没说过的话。 我没有说它不能,也没有说它不脆弱。 我只是说_your_解决方案与默认值_整个生态系统_中的
正如我已经说过几次,我的建议是改为浅合并数组,即tsconfig覆盖tsconfigDefaults因为它对每个非数组属性都有效,并且tsconfig _itself_起作用。
正如我多次说过的那样,可以通过进行重大更改或不进行更改来完成此操作。

请不要说出我的话。 我已经重复了无数次,请阅读我写的实际内容,而不是虚构内容。

问题是,用户为什么应该有权访问图书馆作者禁止的内容?

tsconfig也不禁止,TSDX也不禁止,而rollup-plugin-typescript2也不禁止,所以我不知道您指的是什么。

我们必须具有无法覆盖的tsconfig配置,但与此同时,我们需要有机会对预设进行扩展。 这是重点。

解决方案仅在于新API的设计。

是的,您可以为此添加一个tsconfigConcat选项,这将是一个“新API”。 通过重新发明默认的整个定义来破坏当前的API,会产生一系列新问题和新的不直观行为。 除非深度合并对于数组可能不直观,但它仍然是_correct_行为。 串联只是错误的行为,因为这不是默认值的含义。

tsconfigConcat可以解决您的用例,并且更直观,因为它的名称实际上具有concat,这正是它的作用。
tsconfigDefaults更改

默认= \ =串联。 那不是我的意见,而是定义。

@ agilgur5对不起,但您不能当真。
您的每句话都是有争议的,我已经厌倦了。

我只是争辩说,当前的API根本不允许对其进行任何适当的工作,这就是更改它的原因。
我不再继续了。

好吧,我没有从别人的嘴里吐出来的话,没有读过他们的真实话,没有编造东西,攻击贡献者的性格,提供0个链接,提供0个选择,只考虑一个选项而没有其他选择,那就是你。

如果您想攻击只是试图提供帮助并提供真实定义,真实用例和真实替代品的贡献者,那么我想这就是您的冒犯:shrug:

我想我印象很深,lodash合并实际上在我编写该部分时会合并数组(交错它们或其他东西)。 或者,我什至都不在意数组发生了什么。 由于它显然使用索引作为元素名称覆盖了数组的内容(对吗?这是关于数组的JavaScript最初不是真正的数组,而是字典中恰好有键的数字吗?),因此,我们现在的文档位于其中。

理想情况下,默认/主要/替代tsconfigs选项应允许以相同的毫不奇怪的方式自定义所有参数(标量值和数组)。 Lodash基于索引替换数组元素的方式有一个主要缺点-您无法创建文字稀疏数组(也许是用undefined s填充数组?)。 这意味着必须动态构建汇总配置,而作为json文件的tsconfig根本无法执行。

即使使用文字稀疏数组,基于索引替换元素也太脆弱了。

另一方面,如果通常没有其他行为,则串联是令人惊讶的。 并且单独不允许删除以前的值。

我最初提出的在连接和替换之间进行切换令人惊讶。

@ agilgur5所建议的那样,更改两个合并以替换批发的数组可能是一个最不意外的选择,它将允许删除值,但以不得不重复一个想要保留的值为代价。 不过,这仍然是一项重大突破,人们将不得不为此重写其配置(请参阅https://xkcd.com/1172/)。

我们可以更改这些选项的行为,也可以创建新的集合并使用警告来弃用现有的选项。

(对不起,如果我错过了某个重要的观点,我只会跳过整个主题)

@ezolenko我明白了

让我们看一下情况和动机:
开发人员希望通过汇总插件为打字稿添加一些必要的配置。
在这种情况下,我们不应该阻止开发人员安全地添加设置,并且在合并配置和汇总配置时也不要丢失任何其他设置。

这告诉我们什么? 让我们从语义开始:

正如我之前所说

我同意默认行为。 仅当tsconfig没有相应的属性时才应用默认配置。

我们可以完全重新设计这个东西。

我的建议是:

  1. 当原始tsconfig没有对应的属性时,应用tsconfigDefaults属性。
  2. tsconfigOverride应该注意这一点。
    2.1使用标量值时,它应该像以前一样工作。
    2.2它应该连接数组属性。 (这可能不会破坏任何内容,并且必须符合配置动机)

我只是想避免使用第三个附加的rpt2选项,因为它将使该API复杂至少50%,并且任何开发人员都将不再理解这一点。

@ agilgur5现实与您说的话不是

另外,由于有了电子邮件通知,我阅读了原始消息,并且未编辑8次,以使人们觉得更好。
而且,没有人想要攻击您,没有人这样做。
只是被要求您停止积极进取,并停止在该主题中撰写矛盾的演讲。

  • 0个链接-我花了很多时间来理解问题,充分描述问题,提供示例甚至截图。 而且,我什至研究了您的TSDX,并告诉您您的配置很脆弱,因为我检查了它。 最重要的是,我并没有保持沉默,而是创建了这个问题,以使面临此问题的人员感到困扰。
  • 0个替代方案-请仔细阅读。 我从第一条消息开始提供解决方案。
  • 抽出言语-冷静下来,至少不要自恋,这对我来说是不愉快的。

@maktarsis在您的方法中,开发人员将如何从tsconfig中删除包含或排除条目? 场景是:您有一个在其他地方使用的tsconfig.json,想要在汇总中使用它而不接触json本身,但是出于某种原因,您想从excludes数组中删除一行。

@ezolenko我虽然明白你的意思。

自然地,如上所述,这将是不可能的。
但是,我们谈论的是可能性而不是动力。

我仍然看不到需要重写排除的情况。
尽管如此,我认为我们不需要覆盖dev的“排除”。 换句话说,我无法想象为什么。
有必要了解“由于某些原因”的原因。

如果您希望在任何情况下都具有这种可能性,则需要提供一个附加的API进行串联。
但是,正如您可能理解的那样,我认为它可能是无人认领的,根本就没有必要。
从“排除”中排除某些内容可能根本没有必要,但是如果我们采用其他方法,则会使对配置的理解复杂化。

我们都需要,在数组中添加一些不存在的东西,并从中删除一些东西。 使用浅层合并时,添加和删除都是通过在更高级别上复制整个数组(带有更改)来完成的。 不是很方便,但是可以使用。

"esModuleInterop": true也是如此,这使我的库在某些环境下无法工作。

config.json中的无用编译器选项:

{
   ...
  "compilerOptions": {
       ...
      "esModuleInterop": true,
  },
}

rollup-config中有用的编译器选项:

typescript({
    useTsconfigDeclarationDir: true,
    tsconfigOverride: {
      esModuleInterop: true,
    },
  }),

@maktarsis第一个建议对我来说是预期的行为:

当原始tsconfig没有对应的属性时,请应用tsconfigDefaults属性。

^上面的注释似乎无关紧要,因为它与include或数组无关。 提到的“建议”是tsconfigDefaults已经完成的工作。
我和TSDX也大量使用esModuleInterop ,所以我知道它可以在tsconfig.json ,不确定该注释的含义。 发布的配置也缺少compilerOptions ,它应该是:

js typescript({ useTsconfigDeclarationDir: true, tsconfigOverride: { compilerOptions: { esModuleInterop: true, }, }, }),

但这将覆盖并按预期工作。

此处注意到此回购中先前曾多次提及浅层合并:#86(如我在此处所述,提到了TS的浅层合并行为), https://github.com/ezolenko/rollup-plugin-typescript2/issues/72 #issuecomment -383242460和https://github.com/ezolenko/rollup-plugin-typescript2/issues/208#issuecomment -594237841

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