Visitar URL original
Built-in plugins created by another rolldown package are silently ignored · Issue #11599 · rolldown/rolldown · GitHub
Skip to content

Built-in plugins created by another rolldown package are silently ignored #11599

Open

Description

@danielrentz

Reproduction link or steps

package.json:

{
  "type": "module",
  "dependencies": {
    "rolldown": "1.3.0",
    "rolldown12": "npm:rolldown@1.2.16"
  }
}

src/main.js:

export function load(lang) {
  return import(`./locales/${lang}.js`)
}

src/locales/en.js and src/locales/de.js: export default 'en' and export default 'de'

repro.js:

import { rolldown as rolldown13 } from 'rolldown'
import { rolldown as rolldown12 } from 'rolldown12'
import { dynamicImportVarsPlugin } from 'rolldown/experimental' // from rolldown 1.3.0

for (const [version, rolldown] of [['1.3.0', rolldown13], ['1.2.16', rolldown12]]) {
  const bundle = await rolldown({ input: 'src/main.js', plugins: [dynamicImportVarsPlugin()] })
  const { output } = await bundle.generate({ format: 'esm' })
  const transformed = !output[0].code.includes('import(`')
  console.log(`bundled with rolldown ${version}: dynamic import transformed: ${transformed}`)
}

Run npm install && node repro.js:

bundled with rolldown 1.3.0: dynamic import transformed: true
bundled with rolldown 1.2.16: dynamic import transformed: false

What is expected?

Rolldown applies the built-in plugin, or fails the build with an error that the plugin was created by another rolldown package.

What is actually happening?

Rolldown ignores the plugin without an error or warning, and the bundle contains the untransformed import(`./locales/${lang}.js`). The check plugin instanceof BuiltinPlugin (in bindingify-input-options.ts, normalize-plugin-option.ts and plugin-driver.ts) fails for the BuiltinPlugin class of the other package, so the object ends up as a JS plugin without hooks.

System Info

  System:
    OS: Windows 11 10.0.26300
    CPU: (28) x64 13th Gen Intel(R) Core(TM) i7-13850HX
    Memory: 8.23 GB / 31.66 GB
  Binaries:
    Node: 24.21.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.22 - C:\Program Files\nodejs\yarn.CMD
    npm: 9.8.1 - C:\Program Files\nodejs\npm.CMD
    pnpm: 10.33.4 - C:\Program Files\nodejs\pnpm.CMD
  npmPackages:
    rolldown: 1.3.0 => 1.3.0

Any additional comments?

We publish a plugin package that wraps dynamicImportVarsPlugin and importGlobPlugin from rolldown/experimental, with rolldown as peer dependency. After a dependency update, our project resolved rolldown 1.3.0, while tsdown 0.23.5 depends on rolldown ~1.2.16. tsdown bundled with 1.2.16 and skipped both plugins, and the build succeeded with broken dynamic imports. Every package that returns built-in plugins can run into this when the rolldown of the project differs from the rolldown of tsdown or Vite.

Proposal: the BuiltinPlugin constructor sets a brand such as Symbol.for('rolldown.BuiltinPlugin'), and the plugin normalization throws an error for branded objects that fail the instanceof check, with the plugin name and a hint to install a single rolldown version. Passing such plugins on to the native binding is an alternative, but the options of a built-in plugin can change between versions. I can open a PR for the error if this approach is fine.

As a workaround, our plugin now compares this.meta.rolldownVersion with VERSION from its own rolldown in buildStart and fails the build on a mismatch.

Activity

  1. self-assigned this
    on Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

Priority

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions