Rollup-plugin-typescript2: 在对象内的错误文件夹中生成的打字文件作为“输入”汇总

创建于 2019-02-05  ·  33评论  ·  资料来源: ezolenko/rollup-plugin-typescript2

会发生什么以及为什么会出错

可能这是我的配置错误,但它看起来像一个错误。 当您使用object作为汇总配置的input属性时,输入文件的typings 文件将在存储库的根文件夹(与汇总配置文件相同的文件夹)中生成,并且不是目标输出目录(此处./dist )以及捆绑的 JS 文件。

版本

  • 打字稿:3.2.4
  • 汇总:1.1.2
  • 汇总插件打字稿2:0.19.2

汇总配置文件

{
    ...
    input: {
        Lib1: './src/Lib1.tsx',
        Lib2: './src/Lib2.tsx'
    },
    output: {
        dir: './dist',
        format: 'cjs',
        sourcemap: true,
        entryFileNames: '[name].js'
    }
}

配置文件

{
  ...
  "compilerOptions": {
    "outDir": "./dist"
  },
}

结果:

// These files are created
./Lib1.d.ts
./Lib2.d.ts

// instead of (expected):
./dist/Lib1.d.ts
./dist/Lib2.d.ts

奇怪的是,如果您输入entryFileNames: 'dist/[name].js'它会在dist文件夹中创建一个名为dist的多余子文件夹并在那里创建它们。

bug more info needed

最有用的评论

是的。 这似乎是唯一的方法,除非您让tsc进行端到端的捆绑。
这些汇总插件似乎有效地要求 tsc 执行两个不同的任务:

  1. “类型检查并将所有这些单独的模块转换为 JavaScript”,让我(即 Rollup)进行捆绑和写入磁盘。
  2. “为这个 TS 项目文件夹制作所有声明并将它们转储到那里。”

当您使用“输入映射”和代码拆分等时,1 和 2 的结果不匹配,并且无法匹配。 – AFAICT。

...除非您让汇总插件更多地参与类型声明生成过程。

所有33条评论

useTsconfigDeclarationDir插件选项目前是一种解决方法。

这可能由 #142 修复,在 0.20.0 中发布

@ezolenkom@jakearchibald ,实际上

在我的汇总插件中添加useTsconfigDeclarationDir选项时,根本不再创建声明文件。 不幸的是,更新到 0.20.1 并没有什么不同。

@benkeen使用useTsconfigDeclarationDir: true插件选项时,您还需要在tsconfig.jsondeclarationDir

有类似的烦恼,我的项目布局是这样的:

export default [ 
  {
    input: 'src/subFolder1/one.ts,
    output: [
                    {
                      file: 'dist/one.js'
                      .....                      
                     }
    ],
    plugins: [
           typescript({
                typescript: require('typescript'),
            }),
    ]
  },
      input: 'src/subFolder2/two.ts,
      output: [
                    {
                      file: 'dist/two.js'
                      .....                      
                     }
    ],
     ...
  },
]

作为输出,我有:

  |---subFolder1
  |          |--------one.d.ts
  |
  |---subFolder2
  |          |---------two.d.ts
  |-----one.js
  |-----two.js

使用useTsconfigDeclarationDir: false在 0.20.1 上为我工作 - d.ts 文件进入output.[].dir指定的文件夹。 @benkeen你能再试一次吗?

@AntonPilyak这是设计的——如果 d.ts 进入一个没有子路径的文件夹,那么如果你有subFolder1/one.tssubFolder2/one.ts ,其中一个会覆盖另一个。

@ezolenko :我认为这个功能会带来更多的不便,而不是解决真正的问题(因为很难维护所有这些目录结构)。 我必须创建一个脚本,将所有这些类型声明复制到包的根目录,并将目录添加到 .npmignore 以创建一个易于包含的包。 我建议您仅为具有相同名称的类型文件创建这些附加目录。 其余使用在 rollup.config.json 的“输出”部分中定义的目录。

@AntonPilyak您可能可以使用useTsconfigDeclarationDir: true选项,在 tsconfig 中设置declarationDir ,这应该让 typescript 本身处理打字输出路径。

在不断发展的项目中,决定是否应根据路径的唯一性使用子目录将是一场噩梦,突然您的输入会移动到子文件夹,因为您在不同的文件夹中添加了一个具有相同名称的新文件。

通常,如果您想要漂亮的打字,您无论如何都希望将它们合并到一个文件中(有一个 npm 模块,我一直忘记它的名称)

我使用的是0.22.0 ,我遇到了与

{
    ...
    input: {
        foo: 'src/lorem/foo.ts',
        bar: 'src/ipsum/bar.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

我得到了这个:

dist/
    lorem/
        foo.d.ts
    ipsum/
        bar.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

显然,我希望*.d.ts文件与*.js*.js.map文件放在一起。

我试过摆弄useTsconfigDeclarationDirdeclarationDir无济于事。

定义文件总是分别在loremipsum子文件夹中结束,并且永远不会在平面列表中。

此外,它似乎为找到的每个 .ts 文件创建声明文件,而不仅仅是入口点。

dist/
    lorem/
        foo.d.ts
    ipsum/
        utils/
            bar-helper.d.ts
        bar.d.ts
     some_other_ts_file/
         not_imported_by/
             neither_foo_nor_bar/
                  wat.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

我已经尝试将options.tsconfigOverride.input范围限定tsconfigOverride.input有效。

这一切都有些令人困惑。

...

我的意思是,如果它需要为utils/bar-helper.ts创建一个声明文件就足够wat.ts应该被排除在整个事情之外。

是的,它会为 tsconfig 找到的所有文件生成声明,如果您不想触及特定文件,请确保将其排除或不包含在 tsconfig 中。 要查看打字稿找到的文件列表,请运行详细级别为 3 的插件并查找“已解析的 tsconfig”条目。

对于定义路径,在您的示例中,您希望'src/ipsum/foo.ts'定义位于何处?

因为它是dist/foo.js的定义,所以我认为它会在它旁边结束 - 就像源映射文件一样 - 即在dist/foo.d.ts

TypeScript 会知道将dist/foo.jsdist/lorem/foo.d.ts配对吗?

这崩溃的完整场景是:
src/dir1/foo.ts
src/dir2/foo.ts

dir1/foo.ts 我们设置为汇总输入并导入 dir2/foo.ts。 Rollup 将创建 dist/foo.js 包,其中将包含两个源文件的相关部分,但 typescript 需要在某处创建 2 个具有相同名称的类型定义文件。

简单的解决方案是使用子文件夹,镜像源布局。 我认为这也是tsc所做的,除非你告诉它合并类型定义(rpt2 不支持定义合并)。

是的,打字稿会知道在哪里可以找到类型定义。 所以除了有点乱之外,这应该不是问题。 如果要在 npm 上部署具有类型的包,请将"types"中的package.json为 d.ts 文件作为入口点。 打字稿会从那里找到东西。

啊,所以这个插件并没有真正管理声明构建过程的任何部分。 它只是启动tsc来做它的事情,与 Rollup 的过程无关?

尽管如此,如果我只公开/发布几个模块,为什么我希望 TypeScript 为它遇到的每个 ts 文件生成*.d.ts文件? 有没有办法将它限制在入口点?

事实是,我正在导出一组独立模块( import tool1 from 'myTools/tool1';等),因此在pkg.types没有可以使用的单一入口点。 每个定义文件都必须位于其*.js对应文件旁边,以便 VSCode 可以获取它。

更糟糕的是,如果我有

{
    ...
    input: {
        fooscript: 'src/foo/index.ts',
        barscript: 'src/bar/index.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

我得到:

dist/
    foo/
        index.d.ts
    bar/
        index.d.ts
    fooscript.js
    fooscript.js.map
    barscript.js
    barscript.js.map

现在,TypeScript 无法将dist/fooscript.jsdist/foo/index.d.ts配对。

...

您的插件无法为每个 JavaScript 包文件提供目标/输出路径吗? 似乎 tsc 正在接收原始条目文件名并在生成声明时紧紧抓住它。
...或为每个输入文件寻找相应的*.d.ts文件并将其移动+重命名到输入文件映射目标。 (你可能会注意到我在这里胡说八道,所以...... ;-)

这是我必须在 Rollup 完成后手动尝试的东西 - 但如果插件能够自动处理它会更好。

不,插件使用 LanguageServices(通常使用相同的打字稿 API IDE),所以我可以控制要写的内容和位置。

要为每个汇总输入编写一个类型定义,我们需要为该输入的所有导入合并定义。 Rollup 可能会看到一个输入 ts 文件,但它可能会在构建时导入和捆绑任意数量的源文件,这些文件也需要生成类型。

目前,我在为 typescript 在查看 tsconfig 文件时找到的所有内容生成定义方面犯了错误。 如果我只为转译的模块生成类型,则仅输入类型的文件将被忽略。

我可能不得不重新审视那部分,自从那部分完成后,API 发生了相当大的变化......

我将不得不看看如何使您的示例工作。 可能需要在一个汇总配置中更好地支持多个包。

但是,您如何在构建后使用该包? 这不是您可以在 npm 上发布并按包名导入的东西...

我正在制作一系列独立实用程序。 已发布/已安装包的根文件夹包含平面列表中的所有构建模块文件。

(我将它们写在 TS/ES6 中嵌套的文件夹结构中,混合了测试文件,并依靠 Rollup 将它们转换为 CJS 文件的平面列表,其中有效地混合了代码拆分和内联共享代码。)

然后我通过按文件名导入它们来使用这些工具 - 像这样:

import tool1 from 'myTools/tool1';
import tool2 from 'myTools/tool2';

这个想法是,通过没有整个工具包的单一入口点(没有pkg.mainpkg.module条目),我可以随意添加很少使用的,甚至是实验性的工具没有为下游消费者增加重量/膨胀(这可能没有有效的摇树)。

...我现在在命令行上玩了tsc一点,我想我现在看到了你正在处理的限制。

但是,我注意到,如果您运行 tsc 并将模块/输出格式设置为"amd""system" ,它会生成一个单独的*.d.ts文件,其中包含所有必要的declare module "..."块内联。

我想知道是否可以以某种方式利用这种行为 - 通过文件重命名/移动和解包/重写最后一个(主)模块声明?


旁注:我还注意到tsc似乎并没有花太多精力在摇树该声明文件上。 在一种情况下,我看到一个主要(入口点)模块导出单个非常简单的函数签名,但声明文件公开了“幕后”使用的所有私有模块的声明块。 有趣的。 :-)

你好,我们又见面了。
现在,我正在为tsc设置一个自定义declarationDir以将所有*.d.ts转储到其中,然后运行一个独立脚本,将相同的入口文件导入到-当我提供给 Rollup 时输出文件对象,它生成捆绑目标级别的声明文件,这些文件只是export * from实际的声明文件。

本质上,我生成dist/fooscript.d.ts只包含:

export *  from './__types/foo/index';

这是一个丑陋的独立黑客,但它提供了可预测的正确结果。

我想知道rollup-plugin-typescript2是否可以做类似的事情?

那行得通,是的。

我有一些想法(当我想到它们时),例如生成<bundlename>.d.ts ,其中包含的每个 d.ts 都有一堆/// <reference types=""/>

首先,我可能必须修复生成过多类型声明的相关错误,并将其限制为仅根文件及其实际导入的任何内容。

一些想法:

IMO,我的 hack 唯一真正丑陋的部分是它与 Rollup 过程分开的事实。 中介*.d.ts实际上是在 Rollup 生成的包和tsc的定义之间架起桥梁的一种非常巧妙和惯用的方式。

由于tsc生成的声明文件通过相对路径相互引用,因此最好不要使用该文件/文件夹结构——以免最终为自定义语言语法重新实现部分 Rollup 功能。

如果rollup-plugin-typescript2output.dir + '__types'类的内容设置为默认值declarationDir ,那么由tsc过度热心引起的任何混乱都会被巧妙地扫除-视线在一个明确命名的文件夹中。 这样,无关的定义文件就成为 IMO 的一个非常小的问题。


FWIW,这是我脚本的主要内容:

const { makeInputMap, getEntrypoints, distFolder, srcFolder } = require('./buildHelpers');
const { writeFileSync } = require('fs');
const { relative } = require('path');

const srcPrefixRe = new RegExp('^' + srcFolder + '/');
const tsExtRe = /\.tsx?$/;

const declDirRelative = './' + relative(
  distFolder,
  require('../tsconfig.json').compilerOptions.declarationDir
);

const tsEntrypoints = getEntrypoints()
  .filter((fileName) => tsExtRe.test(fileName));

Object.entries(makeInputMap(tsEntrypoints))
  .forEach(([moduleName, sourcePath]) => {
    const tscDeclFile = sourcePath
      .replace(srcPrefixRe, declDirRelative + '/')
      .replace(tsExtRe, '');
    const outFile = distFolder + '/' + moduleName + '.d.ts';
    writeFileSync(
      outFile,
      [
        'export * from "' + tscDeclFile + '";',
        'import x from "' + tscDeclFile + '";',
        'export default x;',
        '',
      ].join('\n')
    );
  });

console.info('Created local declaration files for TypeScripted entrypoints.');

我更新了上面的示例,因为似乎必须明确重新导出默认导出。

初步测试表明,从没有default导出的声明文件中盲目地重新导出default是无害的,并且会被默默忽略。 (至少 VSCode 是这样。)

嗨,这个问题应该在 v0.23.0 中解决吗?

(......想知道我是否应该尝试更新我的项目以删除所有自定义的faffing)

0.23 不会为所有可见的东西生成声明,但它仍然会生成你实际导入到它们的相关子文件夹中的声明。 您可能可以更新并拥有更轻的类型,但是还没有什么可以生成根类型声明。

我的自定义解决方法构建脚本(见上文)逐渐渗透到我越来越多的项目中。 o_o

仅供参考:官方@rollup/plugin-typescript 包的开发已经恢复,它现在具有类型检查和输出声明文件的功能,所以我个人切换到使用它。
但是,限制大体相同。

@maranomynet在汇总完成后,您是否仍然依靠脚本来移动声明文件? 我没有太多运气改变自己。

是的。 这似乎是唯一的方法,除非您让tsc进行端到端的捆绑。
这些汇总插件似乎有效地要求 tsc 执行两个不同的任务:

  1. “类型检查并将所有这些单独的模块转换为 JavaScript”,让我(即 Rollup)进行捆绑和写入磁盘。
  2. “为这个 TS 项目文件夹制作所有声明并将它们转储到那里。”

当您使用“输入映射”和代码拆分等时,1 和 2 的结果不匹配,并且无法匹配。 – AFAICT。

...除非您让汇总插件更多地参与类型声明生成过程。

啊,是的,我就是这么想的,谢谢! 给您一个 👍 表示您的回答很有帮助,而 👎 表示我对此的感受。

这有什么好运气吗?

对于任何与@maranomynet和我具有相同 src 文件夹结构的苦苦挣扎的灵魂。

我遇到了一个快速修复方法,可能是另一种丑陋的方法,但对我有用。

我正在使用 rollup-plugin/typescript2,所以我将在这个答案中使用它的配置:
在您的 tsconfig.json 中定义您自己的 declarationDir,以便您的项目可以将所有 *.d.ts 文件转储到捆绑的 dist 中自己的路径中。 并确保在汇总配置文件的打字稿插件中将 useTsConfigDeclarationDir 设置为 true。
此外,在您为 rollup.config.js(和 package.json)中的各个组件包定义输出路径的地方,将这些路径更改为与您的“declarationDir”+“您的 src 组件路径如何”相同。 所以如果你在 src 中的组件是这样的:

src/主页/foo.tsx

你的声明目录是:

dist/MyDeclarationDir

所以你的输出路径需要像:

dist/MyDeclarationDir/homepage/foo.js

这样,汇总会将您的类型包含在与组件 main.js 相同的目录中,并且您的 TS 消费者项目将选择类型。

所以捆绑包看起来像:

距离/

    declarationDirPath/
                  component1/
                        foo.js/
                              foo.js
                              foo.map.js
                        foo.d.ts
                   component2/
                        bar.js/
                               bar.js
                               bar.map.js
                        bar.d.ts
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

yangwao picture yangwao  ·  7评论

alireza-salemian picture alireza-salemian  ·  4评论

freeman picture freeman  ·  6评论

brandon-leapyear picture brandon-leapyear  ·  7评论

mikob picture mikob  ·  4评论