Swatinem/rollup-plugin-dts

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:

  1. Setup typeRoots in tsconfig (preferred).
  2. Add /// <reference path="intl-messageformat-parser.d.ts" /> in src/Message.ts, but after that dts-bundle-generator adds declare 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.