Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to import declaration files with this plugin? #273

Closed
thejohnfreeman opened this issue Jun 23, 2021 · 12 comments
Closed

Is it possible to import declaration files with this plugin? #273

thejohnfreeman opened this issue Jun 23, 2021 · 12 comments
Labels
kind: support Asking for support with something or a specific use case problem: stale Issue has not been responded to in some time solution: tsc behavior This is tsc's behavior as well, so this is not a bug with this plugin

Comments

@thejohnfreeman
Copy link

I have a dependency with a single .ts source file that imports declarations from many .d.ts declaration files. When Rollup hits a declaration file, I get a PARSE_ERROR telling me that Rollup is trying to parse the TypeScript declaration file as an ES module. I tracked that down to the exclude setting for this plugin which skips .d.ts files by default. After setting exclude: [], this plugin parses the file, but whatever ES module it returns to Rollup is missing the declarations inside, because I get a MISSING_EXPORT error. Is there a way to see what ES module this plugin is returning for a given TS declaration file? Is there a way to get it to include all the exports in a declaration file?

@ezolenko
Copy link
Owner

For rollup, the problem is that d.ts don't contain any code that translate to java script -- translated d.ts file is an empty js file.

Normally you are not supposed to import d.ts files directly, but let typescript find them itself (by setting types parameter in package, etc).

@ezolenko
Copy link
Owner

Actually, if you have plugin order correctly, rpt2 will translate ts file and those imports will be gone from resulting js file, so rollup should not see d.ts files at all. Could you post output with verbosity 3?

@thejohnfreeman
Copy link
Author

Say I have an index.ts file with this import:

import type Foo from './foo'
declare const foo: Foo
export default foo

Next to this file is foo.d.ts that exports a declaration for Foo.

The code I want to bundfle imports the index.ts module. I want to bundle it as if foo is an external global variable, i.e. that it will exist in the global scope whenever the bundle is executed, and thus the bundle does not need to bundle a dependency that exports foo. How can I accomplish that?

Right now I either get a parse error from Rollup when it goes to parse foo.d.ts (because this plugin ignores .d.ts), or I get a missing import error when this plugin compiles foo.d.ts to an empty module.

@thejohnfreeman
Copy link
Author

I'll try to distill a minimal example to demonstrate, but if you can answer the hypothetical, I'd greatly appreciate it.

@ezolenko
Copy link
Owner

Import type is supposed to get fully erased by typescript, so rollup shouldn't see anything. Are there other plugins in the chain?

@thejohnfreeman
Copy link
Author

Before it in the chain are just @rollup/plugin-node-resolve and @rollup/plugin-commonjs.

@ezolenko
Copy link
Owner

Another way to debug this: if you enable verbosity 3 it will print path to cache files that contain translated js, find one for the ts file that does the import and check if js still has the import for some reason.

Also you could run tsc directly and check if it generates any imports there and if js it produces is different from what plugin makes.

Also check typescript version the plugin uses and make sure it is the one you expect.

@thejohnfreeman
Copy link
Author

Going through the exercise of distilling the problem helped me identify the true cause, and it's unrelated to this plugin. It was the import after the one I first suspected, that imported an enumeration. Following that road led me to this example:

If a .ts module contains declare const foo; export default foo, then the TS compiler will emit export default foo. But if that same constant is exported as a named export, instead of a default export, i.e. declare const foo; export foo, then I would expect export { foo }, but instead the TS compiler emits export {}. That seems to be my problem for now. (If this worked, then the next step would be getting export declare enum Bar { ... } to emit export { Bar }.)

Here is an example you can clone and try. This repository contains two NPM packages named one and two. two depends on one. one exports foo as a default export, and bar as a named export. two imports both of them. Each package has a script named tsc that just runs the TS compiler to emit an ES2015 module so you can see what Rollup sees. The two package has a build script that runs Rollup and hits an error on the missing export of bar (after it found the export for foo).

@ezolenko
Copy link
Owner

I don't think you are using types correctly there. If you expect anything to be actually exported, it needs to be in ts file. Try writing a typescript module that exports what you need (enums, etc) and then run tsc --declaration on it and check what types it generates.

@thejohnfreeman
Copy link
Author

Try writing a typescript module that ...

I did write that TypeScript module. It is the module one/src/bar.ts. It exports a declaration, which I interpret as: "There is a global variable named bar and it has the type number. This module exports an object with a property bar that is the same as the global variable bar."

When I run tsc --declaration, it emits the exact same contents: export declare const bar: number;. So the source file and the declaration file has the export I'm looking for, but the ES2015 module does not.

@ezolenko
Copy link
Owner

ezolenko commented Jun 24, 2021

So the source file and the declaration file has the export I'm looking for, but the ES2015 module does not.

You might have to actually assign that value to a var in the module and then export that. If I do:

declare const bar: number; // convincing ts there is a global var with that name somewhere
export let bar1 = bar; // exporting local var from this module

I get this in js

export var bar1 = bar;

And this in d.ts:

export declare let bar1: number;

For enums, you don't declare them, you define them:

export enum A { a, b, c }
export const enum B { a, b, c }

Makes this js (A is exported and B is erased because typescript will substitute the values directly)

export var A;
(function (A) {
    A[A["a"] = 0] = "a";
    A[A["b"] = 1] = "b";
    A[A["c"] = 2] = "c";
})(A || (A = {}));

And this d.ts

export declare enum A {
    a = 0,
    b = 1,
    c = 2
}
export declare const enum B {
    a = 0,
    b = 1,
    c = 2
}

Unless I misunderstand what you are trying to do :)

@agilgur5 agilgur5 added solution: tsc behavior This is tsc's behavior as well, so this is not a bug with this plugin kind: support Asking for support with something or a specific use case problem: stale Issue has not been responded to in some time labels Apr 24, 2022
@agilgur5 agilgur5 changed the title Is it possible to get this plugin to correctly handle declaration files? Is it possible to import declaration files with this plugin? Apr 24, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented Apr 24, 2022

Going to close this out as I believe this has been answered well and in entirety -- declarations are indeed not supposed to be imported and indeed would not produce valid ES modules. That is TS behavior and not specific to this plugin.

OP also suggested themselves that the issue was not with this plugin and has not responded to further comments.

Note that triple-slash directives may behave differently, which may be what OP intended to do instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case problem: stale Issue has not been responded to in some time solution: tsc behavior This is tsc's behavior as well, so this is not a bug with this plugin
Projects
None yet
Development

No branches or pull requests

3 participants