Skip to content

@rollup/plugin-typescript resolves npm package .js exports to .ts source, breaking bundling of packages that ship TypeScript source alongside compiled output #3664

Description

@almoehi

Ran into this while trying to use a 3d party TS lib. Looks like a trivial fix.

Description

The generated rollup.config.component.mjs configures @rollup/plugin-typescript without an exclude for node_modules. When an npm dependency ships TypeScript source files (.ts) alongside compiled output (.js) in the same directory — and its package.json exports map points to the .js file — the TypeScript plugin's resolveId hook applies TypeScript's standard JS→TS source redirect: it sees ./mod.js and, finding ./mod.ts next to it, substitutes the .ts file instead. Rollup then tries to parse the .ts syntax as plain JavaScript (the TS plugin does not transform node_modules files) and fails with a parse error.

Steps to reproduce

  1. Install any npm package that ships .ts source alongside .js in its package root (example: @bradenmacdonald/s3-lite-client)
  2. Import it in a component source file:
    import '@bradenmacdonald/s3-lite-client'
  3. Run golem build

Error output

[!] RollupError: node_modules/@bradenmacdonald/s3-lite-client/mod.ts (8:7):
    Expected ',', got 'ident'
    (Note that you need plugins to import files that are not JavaScript)

Expected behavior

Rollup resolves the package to its compiled .js entry point (as declared in the exports map) and bundles it successfully.

Suggested fix

Add exclude: ['**/node_modules/**'] to the typescript() plugin options in the generated rollup.config.component.mjs:

 typescript({
     noEmitOnError: true,
+    exclude: ["**/node_modules/**"],
     ...(tsIncludes.length > 0
         ? { include: ["./src/**/*.ts", ...tsIncludes] }
         : {}),
 }),

Compatibility concerns

  • Project source files are unaffected. The exclude only gates the TypeScript plugin's resolveId hook. All project files live under src/, not node_modules/.
  • Consistent with the existing commonjs plugin. That plugin already scopes itself with include: ['node_modules/**'] — both plugins are already treating node_modules as a distinct zone. This makes the TypeScript plugin consistent with that pattern.
  • Type-checking is unaffected. TypeScript type-checking of dependencies happens in the separate tsc --emitDeclarationOnly step driven by tsconfig.json, which is independent of rollup plugin configuration.
  • The transform hook already skips node_modules. The TypeScript plugin's compile step does not process node_modules by default — this fix only closes the same gap in the resolveId hook.
  • Only affects packages with a .ts/.js collision. Packages that ship only compiled .js (the large majority) are completely unaffected: without a .ts companion file at the same path, the redirect never fires.

Environment

golem 1.5.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions