可能这是我的配置错误,但它看起来像一个错误。 当您使用object
作为汇总配置的input
属性时,输入文件的typings 文件将在存储库的根文件夹(与汇总配置文件相同的文件夹)中生成,并且不是目标输出目录(此处./dist
)以及捆绑的 JS 文件。
{
...
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
的多余子文件夹并在那里创建它们。
useTsconfigDeclarationDir
插件选项目前是一种解决方法。
这可能由 #142 修复,在 0.20.0 中发布
嗨@ezolenkom和@jakearchibald ,实际上
在我的汇总插件中添加useTsconfigDeclarationDir
选项时,根本不再创建声明文件。 不幸的是,更新到 0.20.1 并没有什么不同。
@benkeen使用useTsconfigDeclarationDir: true
插件选项时,您还需要在tsconfig.json
有declarationDir
值
有类似的烦恼,我的项目布局是这样的:
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.ts
和subFolder2/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
文件放在一起。
我试过摆弄useTsconfigDeclarationDir
和declarationDir
无济于事。
定义文件总是分别在lorem
和ipsum
子文件夹中结束,并且永远不会在平面列表中。
此外,它似乎为找到的每个 .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.js
和dist/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.js
和dist/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.main
或pkg.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-typescript2
将output.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 和 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
最有用的评论
是的。 这似乎是唯一的方法,除非您让
tsc
进行端到端的捆绑。这些汇总插件似乎有效地要求 tsc 执行两个不同的任务:
当您使用“输入映射”和代码拆分等时,1 和 2 的结果不匹配,并且无法匹配。 – AFAICT。
...除非您让汇总插件更多地参与类型声明生成过程。