Use-cases of incorrect result for dts-bundle-generator
timocov opened this issue ยท 6 comments
Hi @Swatinem!
I'm creator of dts-bundle-generator. Actually this isn't an issue of your tool, but just a little question - you've mentioned in the readme file that
dts-bundle-generator which was a good inspiration for this project but in the end didnโt really work as well for my use-cases.
Can you please provide some examples, where dts-bundle-generator doesn't work well for your use-cases? Your cases might be useful to improve dts-bundle-generator and I would appreciated you for providing additional interesting examples.
Thanks in advance!
Hi @timocov and thanks for reaching out :-)
So one of the reasons is your well documented list of limitations, which are quite limiting considering how I like to usually structure my code.
Most of those work just fine in rollup-plugin-dts
due to the fact that it is based on rollup.
1 / 3 https://github.com/Swatinem/rollup-plugin-dts/blob/master/src/__tests__/testcases/renaming/index.ts
4 https://github.com/Swatinem/rollup-plugin-dts/blob/master/src/__tests__/testcases/re-export-default/index.ts
But I noticed that I hit a quite hard wall when trying to re-export namespaces (https://github.com/Swatinem/rollup-plugin-dts/blob/master/src/__tests__/testcases/re-export-namespace/index.ts)
Iโm not sure if it is even possible to solve ๐, or if I can somehow hook more deeper into rollup to fix that caseโฆ
The other thing is that I use one of my other projects intl-codegen as a guineapig here, and for some reason it does not work as well with dts-bundle-generator
:
> npx dts-bundle-generator --project tsconfig.json src/index.ts
src/Message.ts(1,61): error TS7016: Could not find a declaration file for module 'intl-messageformat-parser'. '/home/swatinem/Coding/eversports/intl-codegen/node_modules/intl-messageformat-parser/index.js' implicitly has an 'any' type.
Try `npm install @types/intl-messageformat-parser` if it exists or add a new declaration (.d.ts) file containing `declare module 'intl-messageformat-parser';`
I have explicitly typed that external module here: https://github.com/eversport/intl-codegen/blob/master/src/intl-messageformat-parser.d.ts and it works just fine both with tsc
and with rollup-plugin-dts
.
Also, using it on the rollup-plugin-dts
codebase itself works, but has two problems:
/// <reference types="estree" />
/// <reference types="node" />
import { PluginImpl } from 'rollup';
import { CompilerOptions, ts } from 'typescript';
export declare enum CompileMode {
Types = "dts",
Js = "js"
}
export interface Options {
include?: Array<string>;
exclude?: Array<string>;
tsconfig?: string;
compilerOptions?: ts.CompilerOptions;
compileMode?: CompileMode;
}
export declare const plugin: PluginImpl<Options>;
export declare const dts: PluginImpl<Options>;
export declare const js: PluginImpl<Options>;
export default plugin;
vs
import { CompilerOptions } from 'typescript';
import { PluginImpl } from 'rollup';
declare enum CompileMode {
Types = "dts",
Js = "js"
}
interface Options {
include?: Array<string>;
exclude?: Array<string>;
tsconfig?: string;
compilerOptions?: CompilerOptions;
compileMode?: CompileMode;
}
declare const plugin: PluginImpl<Options>;
declare const dts: PluginImpl<Options>;
declare const js: PluginImpl<Options>;
export default plugin;
export { CompileMode, plugin, dts, js, js as ts };
There are multiple problems here:
- the invalid
import {ts} from 'typescript'
(might be related to your limitation regarding namespace imports?) - the missing
export {js as ts}
- those "tripleslash" references, which TBH I have never really understood. I would like the
.d.ts
file to be as close to em modules as possible while trying to avoid typescript-isms, which I consider these tripleslash references to be.
But nevertheless, your project is still a great inspiration and influence. I have seen that you are actually (trying to) check the validity of the generated .d.ts
file, which I think I will also integrate into my project.
BEWARE: The generated file could not be properly checked due enabled "skipLibCheck" compiler option
I think you can just override that compilerOptions
flag to check the output .d.ts
file regardless, I will create an issue for you :-)
Also I have seen that you referenced me here: timocov/dts-bundle-generator#68 (comment) (will have to read that whole discussion at some point) so thanks for that :-)
Thanks you @Swatinem for detailed answer ๐!
Most of those work just fine in
rollup-plugin-dts
due to the fact that it is based on rollup.
๐ฎ Whoa, it looks great! I've thought about renaming/use original imports in timocov/dts-bundle-generator#59, but didn't start work on it yet ๐
But I noticed that I hit a quite hard wall when trying to re-export namespaces
Oh yeah, namespaces are hard to work with they ๐
The other thing is that I use one of my other projects intl-codegen as a guineapig here, and for some reason it does not work as well with
dts-bundle-generator
:
I just checked what's going on there. It seems that rollup-plugin-dts
compiles the whole project and src/intl-messageformat-parser.d.ts
is added to the program - that's why both tsc
and rollup-plugin-dts
works fine with that. dts-bundle-generator
to reduce compile units pass only entry point to the compiler, but as soon nothing imports src/intl-messageformat-parser.d.ts
file (not declared there module), it fails. To fix this there are 2 possible solutions:
- Setup
typeRoots
in tsconfig (preferred). - Add
/// <reference path="intl-messageformat-parser.d.ts" />
insrc/Message.ts
, but after thatdts-bundle-generator
addsdeclare module ...
to generated output, because the tool treats it as declared in this project declaration (not outside).
I believe that the first is more correct way in this situation, because you trying to declare outside module, and it should be declared in types to treat this module "from outside". I'm not sure about that, but it looks logic/correct for me.
js as ts
๐ค ๐
the invalid
import {ts} from 'typescript'
(might be related to your limitation regarding namespace imports?)
Maybe, I need check it - it looks strange. But namespaces are hard thing ๐
the missing
export {js as ts}
Hm, I need to check it.
those "tripleslash" references
They can be removed via setting --external-types
.
your project is still a great inspiration and influence.
Thank you! You've solved some hard problems in rollup-plugin-dts
and it deserves respect ๐. I'll try to figure out how you did it to try to port fixes to dts-bundle-generator
.
the invalid
import {ts} from 'typescript'
(might be related to your limitation regarding namespace imports?)
In this case it's import * as
limitation. This can be fixed via import { CompilerOptions } from 'typescript'
instead of import * as ts from 'typescript'
.
the missing
export {js as ts}
dts-bundle-generator
removes all exports and adds owns if it decides to export some node. In this case it removes the whole export { CompileMode, plugin, dts, js, js as ts }
, but it doesn't support renaming in the export. A workaround for this: you can add const ts = js
and then export just ts
without renaming (also in this case we need to avoid import * as ts
import). It's a bug, but I don't know how it can be fixed for now.
dts-bundle-generator
removes all exports and adds owns if it decides to export some node.
So you already parse the exports? In that case it should be trivial to support renames.
I'll try to figure out how you did it
I use typescript to transform .ts
-> .d.ts
, then parse that .d.ts
again.
From that AST, I generate a fake JS AST just for rollup. See https://github.com/Swatinem/rollup-plugin-dts/blob/master/docs/how-it-works.md
And then rollup does the rest.
Problem is that it is a specialized bundler for .js
files, and creates normal JS for some constructs, such as export namespace
: #7 (comment)
Heads up:
I updated my Readme, pointing to this issue and other discussions: https://github.com/Swatinem/rollup-plugin-dts#alternatives feel free to voice any suggestions.