Skip to content

[TypeScript] Module resolution doesn't work in rollup.config.ts when using modern project settings #1662

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

Closed
jdharrisnz opened this issue Jan 10, 2024 · 11 comments

Comments

@jdharrisnz
Copy link

Expected Behavior

Compile as usual. Use npm run bug in my repl to see what happens.

Actual Behavior

Produces errors when compiling:

npx rollup --config rollup.config.ts --configPlugin typescript
loaded rollup.config.ts with warnings
(!) Plugin typescript: @rollup/plugin-typescript TS2349: This expression is not callable.
  Type 'typeof import("/home/runner/rollup-plugin-repro-typescript-import/node_modules/@rollup/plugin-typescript/types/index")' has no call signatures.

Additional Information

Key ingredients are:

  • "type": "module" in package.json
  • "moduleResolution": "NodeNext" or "Node16" in tsconfig.json
  • A rollup config file written in ESM format and TypeScript

The workaround is to use a JavaScript config file, so this is really the smallest of inconveniences, but it's something to fix nonetheless.

@07akioni
Copy link

Same issue encountered.

@thisisanto
Copy link

Alternatively

// @ts-expect-error see https://github.com/rollup/plugins/issues/1662
commonjs(),

Which again isn't nice, but allows you to keep using a TS config file.

@Arnesfield
Copy link

Might be off-topic, but here is another workaround to keep the typings:

// rollup.config.ts
import _eslint from '@rollup/plugin-eslint';
import _typescript from '@rollup/plugin-typescript';

// NOTE: remove once import errors are fixed for their respective packages
const eslint = _eslint as unknown as typeof _eslint.default;
const typescript = _typescript as unknown as typeof _typescript.default;

// ...
export default {
  // ...
  plugins: [eslint(), typescript()]
};

@Silic0nS0ldier
Copy link

Silic0nS0ldier commented Jun 25, 2024

This issue sounds like microsoft/TypeScript#58890

The cause appears to be related to how TypeScript classifies imports. microsoft/TypeScript#58890 (comment) concluded that if the .d.ts file is in a CJS scope, the import will be treated CJS.

In the case of @rollup/plugin-commonjs the types live at types/index.d.ts which is outside the ESM scope (dist/es/).

This issue is fixable, but it will mean duplicating .d.ts in the published package.

EDIT: This also affects @rollup/plugin-json, and likely any other plugin in this collection that uses default exports.

@cowwoc
Copy link

cowwoc commented Sep 9, 2024

@Arnesfield's workaround failed for me with the following error:

@rollup/plugin-typescript TS2339: Property 'default' does not exist on type '(options?: RollupCommonJSOptions | undefined) => Plugin<any>'.

I had to specify the type explicitly for it to work. In the case of rollupCommonJs the options (RollupCommonJSOptions) are not exported, so you can map them to unknown instead:

import _rollupCommonJs from "@rollup/plugin-commonjs";
import _rollupTypescript, {type RollupTypescriptOptions} from "@rollup/plugin-typescript";

const rollupCommonJs = _rollupCommonJs as unknown as (options?: unknown) => Plugin;
const rollupTypescript = _rollupTypescript as unknown as (options?: RollupTypescriptOptions) => Plugin;

I hope this helps.

@Mister-Hope
Copy link

Interested to find out that no one pick this, I believe at least some of the maintainer should leave a message guiding us a expected solution to fix this.

For me, I would prefer to add type: module in package.json directly, this can still remain these packages to be a valid cjs/esm dual packages.

@brandongit2
Copy link

brandongit2 commented Feb 11, 2025

@Silic0nS0ldier Your answer is almost correct, but there is a singular solution to this problem.

package.json:

{
    "name": "@rollup/plugin-typescript",
    "exports": {
        "import": {
            "types": "./types/index.d.mts",
            "default": "./dist/es/index.js"
        },
        "require": {
            "types": "./types/index.d.ts",
            "default": "./dist/cjs/index.js"
        }
    }
}

This would require creating a new index.d.mts declaration file, which I believe (but need to confirm) can just be a symlink to the existing index.d.ts file.


Update: It looks like there's already a PR open which does exactly this: #1782

Just need to wait for a test fix and a merge!

@stale stale bot added the x⁷ ⋅ stale label Apr 26, 2025
Copy link

stale bot commented Apr 27, 2025

Hey folks. This issue hasn't received any traction for 60 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it.

@Mister-Hope
Copy link

.

Copy link

stale bot commented Apr 28, 2025

Hey folks. This issue hasn't received any traction for 60 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it.

@stale stale bot closed this as completed Apr 28, 2025
@AverageHelper
Copy link

apparently #1782 is meant to help with this? @Stale please consider reopening...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants