Skip to content

test(repo): test all packages against their earliest supported rollup versions - #2035

Open
lukastaegert wants to merge 43 commits into
masterfrom
test-earliest-supported-rollup
Open

lukastaegert wants to merge 43 commits into
masterfrom
test-earliest-supported-rollup

Conversation

@lukastaegert

@lukastaegert lukastaegert commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Rollup Plugin Name: all

This PR contains:

  • bugfix
  • feature
  • refactor
  • documentation
  • other

Are tests included?

  • yes (bugfixes and features will not be merged without tests)
  • no

Breaking Changes?

  • yes (breaking changes will not be merged unless absolutely necessary)
  • no

If yes, then include "BREAKING CHANGES:" in the first commit message body, followed by a description of what is breaking.

List any relevant issue numbers:

Description

I am finally starting to prepare for the release of v5 of rollup! This will also mean that plugins need to be made ready, or at least have their peerDependency range extended.

As a very first step, I wondered if it would not make sense to run plugin tests twice, once for the initial supported rollup version and once for the latest version. That way, we know if changes break the promised peerDependency range.

The way I implemented it was to add a second alias rollup-earliest to the devDependencies of each package reflecting the earliest supported version. As there are subtle differences between the versions, tests check the rollup version in relevant places. Snapshot tests are double when needed.

I also switched all packages to a "catalog" latest rollup version, which allows to update that version in a central place without changing the packages. Next steps in the Rollup 5 plan would be:

  1. Create separate pull requests for packages that need fixes to support rollup 5. For all updated packages, change the rollup version from the current catalog version to a Rollup 5 rc version (once we are sure all breaking changes are accounted for)
  2. Create one pull request to update the peerDependency ranges of the remaining packages
  3. Release Rollup 5
  4. Create separate pull requests to update some packages to follow new Rollup 5 best practices (will be breaking changes).

Let me know what you think, and if we should change anything about the current pull request.

Findings from this PR:

  1. @rollup/plugin-html is pinned to 1.21.0 instead of its declared floor
    1.20.0: the plugin's entry detection relies on the bundle file type
    property, which rollup only adds from 1.21.0 on — at 1.20.0 the plugin emits
    HTML without script tags. As that means that 1.20.0 was never supported in the recent past anyway, I would recommend to fix this in an independent patch release, or include this with the peerDependency range extension.
  2. Running the @rollup/plugin-auto-install tests through a pnpm script puts
    the workspace-level node_modules/.bin into PATH, so the package installs
    spawned by the plugin resolved the workspace's own pnpm and regenerated the
    root lockfile with only the fixture importers. The pnpm fixture tests now
    remove that directory from PATH for their duration and assert the root
    lockfile stays untouched. However one might wonder if this should not be fixed in the plugin code itself, but this would be a breaking change and exceeds what I want to do here.
  3. @rollup/plugin-babel is pinned to 2.78.0 instead of its declared floor because it uses an object hook that is only supported since this version. So like the html plugin, the peerDependency range is wrong, which should be fixed in an independent patch release.

…llup

When vitest runs with mode "earliest", both imports and requires of rollup
resolve to the package-local rollup-earliest dependency so that each package
can test against the earliest rollup version it declares to support.
…mode

Test helpers such as @rollup/plugin-node-resolve can require a newer
rollup than a package's own peer floor. Redirect every devDependency
declared as `<name>-earliest` instead of only rollup so packages can
pin old helper versions next to rollup-earliest. The guard against
missing installs now covers every declared alias.
When the output of a package drifts between rollup versions, a single
snapshot file cannot cover both. In earliest mode, prefer a snapshot
file in test/snapshots-earliest over the shared one if it exists, so
packages can opt in per test file.
To act as the "current stable" in all packages.
Run the test suite a second time with rollup pinned to the earliest
supported version (4.0.0) and adapt the plugin warning assertion, whose
message gained a prefix in rollup 4.13.0.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). As the existing tests only call the plugin
hooks directly, add a test that runs an actual build so the pinned
version is exercised.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.78.0). The root @rollup/plugin-typescript now
links the added rollup as its optional peer.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (2.78.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). Accept the `export default` rendering of
the default export by rollup 1.x.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (2.78.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). As the existing tests only call the plugin
hooks directly, add a test that runs an actual build so the pinned
version is exercised.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). As the existing tests only call the plugin
hooks directly, add a test that runs an actual build so the pinned
version is exercised.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.0.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (3.0.0). The root @rollup/plugin-typescript now
links the added rollup as its optional peer.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).

The preserveModules tests are skipped below rollup 3 as they rely on
output.preserveModules, which does not exist at the floor.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.0.0).

Accept that rollup 2 does not emit sourcemaps as separate assets.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.53.1).
Run the test suite a second time with rollup pinned to the earliest
supported version (2.0.0).

Use output options that render identically across rollup versions and
accept that rollup 2 does not emit sourcemaps as separate assets.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).

Skip the output plugin test below rollup 3 as output plugins do not exist
at the floor and rollup 2 does not add the sourcemap comment on generate.
Accept the quoted plugin name in rollup 1 sourcemap warnings and only
snapshot stable warning properties, as rollup 1 adds an enumerable toString.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). @rollup/plugin-node-resolve is pinned to
11.2.1, the last version supporting rollup 1.

The arbitrary export names test is skipped below rollup 3.9 as string
export names are not supported there, and below rollup 3 errors are
named "Error" instead of "RollupError".
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). @rollup/plugin-node-resolve is pinned to
11.2.1, the last version supporting rollup 1.
Run the test suite a second time with rollup pinned to 2.78.0. As the
plugin uses object-form hooks, which rollup only supports from 2.78.0,
this deviates from the declared peer floor of 2.0.0.

Accept the different unresolved-import warning format and chunk hash of
rollup 2 and pin the interop option in the transform-runtime test so
that rollup 2 renders the same output.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0). @rollup/plugin-node-resolve is pinned to
11.2.1, the last version supporting rollup 1.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.68.0). @rollup/plugin-node-resolve is pinned to
13.3.0, the last version supporting rollup 2.68.

Branch expectations on the rollup version where interop helpers, parse
error frames, resolveId options and warning properties differ, and fork
the snapshots whose rendered output differs in rollup 2. Let three
fixture resolveId hooks skip themselves explicitly, as rollup 2 does
not do so by default and recurses infinitely. Pass the active rollup to
the worker of the caching test, which does not inherit the earliest
redirection. Skip the shebang test as rollup 2 cannot parse hashbangs;
the plugin itself fails on shebang modules at that version.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.14.0). @rollup/plugin-commonjs is pinned to
14.0.0, the last version supporting rollup 2.14.

Branch expectations on the rollup version where inlineDynamicImports
and preserveModules are still input options, bundle.close is missing,
entry chunks are emitted in a different order and the pinned commonjs
plugin does not unwrap the default export of __esModule modules. Fork
the snapshots whose serialized errors and warnings differ at that
version.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).

Skip the import assertions fixture for rollup versions before 3.0.0,
whose bundled parser does not understand import assertions yet, and
fork the snapshots because rollup 1 uses a different chunk hash format.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).

Fork the snapshots because rollup 1 renders the default export of the
entry module as `export default x` while rollup 4 uses
`export { x as default }`.
Run the test suite a second time with rollup pinned to 1.21.0, the
earliest rollup version the plugin works with: it detects entry chunks
via the bundle file type property, which rollup only adds to output
files from 1.21.0, although the declared peer range starts at 1.20.0.

Fork the snapshots because rollup 1 renders UMD and IIFE wrappers
differently, hashes chunks differently and warns differently about
empty bundles.
Run the test suite a second time with rollup pinned to the earliest
supported version (2.78.0).

Branch the expected resolveId options on the rollup version, which
gained an "assertions" property in rollup 3 and an "attributes"
property in rollup 4, and branch the fields and message wording of
unresolved import warnings and entry errors, which changed in
rollup 3. Fork the snapshots whose warnings and error messages
differ in rollup 2.
Run the test suite a second time with rollup pinned to the earliest
supported version (1.20.0).

As the tests spawn the rollup CLI as a subprocess, bypassing the
earliest-mode module redirect, resolve the CLI from the rollup module
that is active in the current test mode. The CLI output for the tested
scenarios only differs in timing, which the snapshot normalization
already covers, so the snapshots do not need to be forked.
Run the earliest-rollup test suites for all changed packages in the
validation and Windows pipelines next to the regular test runs.

Document the earliest test mode and its snapshot handling for
contributors.
@lukastaegert
lukastaegert force-pushed the test-earliest-supported-rollup branch from fc1203f to 116b199 Compare October 27, 2026 15:33
Running the tests through a pnpm script adds the workspace-level
node_modules/.bin to the PATH. The package installs spawned by the
plugin then use the workspace's own pnpm, which resolves the monorepo
workspace root and regenerates the root lockfile with only the fixture
importers.

Remove that directory from the PATH for the duration of the pnpm
fixture tests and assert the root lockfile stays untouched.
@lukastaegert
lukastaegert force-pushed the test-earliest-supported-rollup branch from 00d1d4a to f79b4a2 Compare October 27, 2026 15:57
On slow CI runners, heavy tests like the TypeScript declaration
tests can exceed the five seconds that vitest allows by default.
Increase the shared test timeout to twenty seconds so that runner
speed does not decide test outcomes.
@lukastaegert
lukastaegert marked this pull request as ready for review October 27, 2026 17:38
Copilot AI balanced review requested due to automatic review settings October 27, 2026 17:38
@greptile-apps

greptile-apps Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new blocking issues were found.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Package tests] --> B{Test mode}
  B -->|Default| C[Catalog Rollup version]
  B -->|Earliest| D[Earliest dependency aliases]
  C --> E[Regular snapshots]
  D --> F{Earliest snapshot exists?}
  F -->|Yes| G[Earliest snapshots]
  F -->|No| E
Loading

Reviews (3) · Last reviewed commit: "test(typescript): await restoring the fi..." · Reviewed by Greptile

Comment thread packages/html/test/snapshots/test.js.snap Outdated
Comment thread packages/virtual/test/types.test.js Outdated
Comment thread packages/auto-install/test/pnpm.js Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The Rollup upgrade leaves incompatible CLI type checks, and compatibility coverage needs correction before approval.

3 open issues
1 file not reviewed
  • pnpm-lock.yaml: Generated file
What changed in this PR

This PR adds earliest-supported Rollup testing across the plugin monorepo, preparing compatibility checks for Rollup 5 without changing plugin runtime code.

Changes:

  • Add package-specific earliest-version aliases, shared test resolution, and CI runs.
  • Centralize the current Rollup version and adapt tests and snapshots for version differences.
  • Add integration tests, isolate pnpm installation fixtures, and document earliest-mode usage.
File Description
README.md Documents earliest-mode tests and snapshot updates.
pnpm-workspace.yaml Centralizes the current Rollup dependency.
packages/​yaml/​package.json Adds catalog dependency and earliest-mode testing.
packages/​wasm/​test/​test.mjs Tests helper branches across Rollup versions.
packages/​wasm/​package.json Adds catalog dependency and earliest-mode testing.
packages/​virtual/​test/​types.test.js Handles disposable-library availability in type tests.
packages/​virtual/​test/​rollup-build.test.js Adds a real Rollup integration test.
packages/​virtual/​package.json Adds catalog dependency and earliest-mode testing.
packages/​url/​test/​snapshots-earliest/​test.js.snap Adds earliest-version output snapshots.
packages/​url/​package.json Adds catalog dependency and earliest-mode testing.
packages/​typescript/​test/​tslib.js Adapts preserveModules placement for older Rollup.
packages/​typescript/​test/​test.js Adapts assertions and options across versions.
packages/​typescript/​test/​snapshots/​warnings.js.snap Updates current-version warning snapshots.
packages/​typescript/​test/​snapshots/​tslib.js.snap Updates current-version error snapshot.
packages/​typescript/​test/​snapshots-earliest/​warnings.js.snap Adds earliest-version warning snapshots.
packages/​typescript/​test/​snapshots-earliest/​tslib.js.snap Adds earliest-version error snapshot.
packages/​typescript/​package.json Adds earliest Rollup and CommonJS aliases.
packages/​terser/​test/​test.js Handles version-dependent sourcemap output counts.
packages/​terser/​package.json Adds catalog dependency and earliest-mode testing.
packages/​swc/​package.json Adds catalog dependency and earliest-mode testing.
packages/​sucrase/​package.json Adds catalog dependency and earliest-mode testing.
packages/​strip/​test/​rollup-build.test.js Adds a real stripping integration test.
packages/​strip/​package.json Adds catalog dependency and earliest-mode testing.
packages/​run/​test/​test.js Handles version-dependent error prefixes.
packages/​run/​package.json Adds catalog dependency and earliest-mode testing.
packages/​replace/​test/​sourcemaps.js Adapts sourcemap warning expectations.
packages/​replace/​test/​snapshots/​misc.js.snap Updates current-version warning snapshot.
packages/​replace/​test/​snapshots-earliest/​misc.js.snap Adds earliest-version warning snapshots.
packages/​replace/​test/​misc.js Gates output-plugin coverage and normalizes warnings.
packages/​replace/​package.json Adds catalog dependency and earliest-mode testing.
packages/​pluginutils/​package.json Adds catalog dependency and earliest-mode testing.
packages/​node-resolve/​test/​test.mjs Adapts resolution and diagnostic expectations.
packages/​node-resolve/​test/​snapshots/​test.mjs.snap Updates current-version warning snapshot.
packages/​node-resolve/​test/​snapshots-earliest/​test.mjs.snap Adds earliest-version snapshots.
packages/​node-resolve/​test/​snapshots-earliest/​prefer-builtins.js.snap Adds earliest-version empty-chunk warning snapshot.
packages/​node-resolve/​test/​prefer-builtins.js Handles version-dependent warning prefixes.
packages/​node-resolve/​test/​jail.js Handles older unresolved-import warning fields.
packages/​node-resolve/​package.json Adds catalog dependency and earliest-mode testing.
packages/​multi-entry/​test/​test.mjs Gates version-dependent preserveModules tests.
packages/​multi-entry/​package.json Adds catalog dependency and earliest-mode testing.
packages/​legacy/​package.json Adds catalog dependency and earliest-mode testing.
packages/​json/​test/​test.js Adapts syntax coverage and error expectations.
packages/​json/​package.json Adds earliest Rollup and resolver aliases.
packages/​inject/​test/​rollup-build.test.js Adds a real injection integration test.
packages/​inject/​package.json Adds catalog dependency and earliest-mode testing.
packages/​image/​package.json Adds catalog dependency and earliest-mode testing.
packages/​html/​test/​snapshots/​test.js.snap Updates current-version output and warnings.
packages/​html/​test/​snapshots-earliest/​test.js.snap Adds earliest-version HTML snapshots.
packages/​html/​package.json Adds earliest-mode testing with the documented exception.
packages/​graphql/​package.json Adds catalog dependency and earliest-mode testing.
packages/​esm-shim/​test/​test.js Normalizes sourcemap and CommonJS output expectations.
packages/​esm-shim/​test/​snapshots/​test.js.snap Reflects hidden sourcemap output.
packages/​esm-shim/​package.json Adds catalog dependency and earliest-mode testing.
packages/​eslint/​package.json Adds earliest Rollup and resolver aliases.
packages/​dynamic-import-vars/​test/​snapshots/​rollup-plugin-dynamic-import-vars.test.js.snap Updates current-version chunk hashes.
packages/​dynamic-import-vars/​test/​snapshots-earliest/​rollup-plugin-dynamic-import-vars.test.js.snap Adds earliest-version bundle snapshots.
packages/​dynamic-import-vars/​test/​rollup-plugin-dynamic-import-vars.test.js Gates import assertions and adapts warnings.
packages/​dynamic-import-vars/​package.json Adds catalog dependency and earliest-mode testing.
packages/​dsv/​package.json Adds catalog dependency and earliest-mode testing.
packages/​data-uri/​package.json Adds catalog dependency and earliest-mode testing.
packages/​commonjs/​test/​test.js Adapts diagnostics, worker setup, and syntax coverage.
packages/​commonjs/​test/​snapshots/​function.js.snap Updates current-version bundle snapshots.
packages/​commonjs/​test/​snapshots-earliest/​test.js.snap Adds earliest-version bundle snapshots.
packages/​commonjs/​test/​helpers/​util.js Makes fixture context and interop version-aware.
packages/​commonjs/​test/​fixtures/​samples/​caching/​rollupWorker.js Loads the selected Rollup version in workers.
packages/​commonjs/​test/​fixtures/​function/​warn-this-resolve-without-options/​_config.js Adapts resolver warning prefixes.
packages/​commonjs/​test/​fixtures/​function/​unresolved-dependencies/​_config.js Adapts unresolved-import warning fields.
packages/​commonjs/​test/​fixtures/​function/​transpiled-esm-namespace-named/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​strict-requires-debug-none/​_config.js Adapts debug warning prefixes.
packages/​commonjs/​test/​fixtures/​function/​module-side-effects-require-wrapped/​_config.js Explicitly skips recursive self-resolution.
packages/​commonjs/​test/​fixtures/​function/​module-side-effects-late-entry/​_config.js Handles version-dependent entry naming.
packages/​commonjs/​test/​fixtures/​function/​module-side-effects-import-wrapped/​_config.js Explicitly skips recursive self-resolution.
packages/​commonjs/​test/​fixtures/​function/​module-meta-properties/​_config.js Explicitly skips recursive self-resolution.
packages/​commonjs/​test/​fixtures/​function/​import-esm-require-returns-default-undefined/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​import-esm-require-returns-default-namespace/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​import-esm-require-returns-default-function-external/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​import-esm-require-returns-default-false/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​import-esm-require-returns-default-auto/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​esm-externals-true/​main.js Adapts external namespace expectations.
packages/​commonjs/​test/​fixtures/​function/​custom-options/​_config.js Adapts resolveId option expectations.
packages/​commonjs/​package.json Adds earliest Rollup and resolver aliases.
packages/​buble/​test/​test.js Handles older default-export formatting.
packages/​buble/​package.json Adds catalog dependency and earliest-mode testing.
packages/​beep/​test/​test.js Runs the CLI from the selected Rollup dependency.
packages/​beep/​package.json Adds catalog dependency and earliest-mode testing.
packages/​babel/​test/​as-output-plugin.mjs Adapts warnings and chunk hashes.
packages/​babel/​test/​as-input-plugin.mjs Adapts unresolved-import warnings and interop.
packages/​babel/​package.json Adds catalog dependency and earliest-mode testing.
packages/​auto-install/​test/​pnpm.js Checks that fixture installs preserve the root lockfile.
packages/​auto-install/​test/​pnpm-bare.js Checks that bare installs preserve the root lockfile.
packages/​auto-install/​test/​fixtures/​pnpm/​pnpm-workspace.yaml Anchors workspace detection to the fixture.
packages/​auto-install/​test/​fixtures/​pnpm/​.npmrc Allows installation at the fixture workspace root.
packages/​auto-install/​test/​fixtures/​pnpm-bare/​pnpm-workspace.yaml Anchors workspace detection to the bare fixture.
packages/​auto-install/​test/​fixtures/​pnpm-bare/​.npmrc Allows installation at the bare fixture root.
packages/​auto-install/​package.json Adds earliest Rollup and resolver aliases.
packages/​alias/​test/​alias.test.ts Adapts warning prefixes across versions.
packages/​alias/​package.json Adds catalog dependency and earliest-mode testing.
.github/​workflows/​validate.yml Adds earliest-version CI tests.
.github/​workflows/​node-windows.yml Adds serial earliest-version Windows tests.
.github/​CONTRIBUTING.md Documents snapshot locations and earliest-mode usage.
.config/​vitest.setup.earliest.mts Redirects CommonJS resolution to earliest dependencies.
.config/​vitest.earliest.mts Discovers and validates earliest dependency aliases.
.config/​vitest.config.mts Configures earliest aliases, snapshots, setup, and timeout.

Review effort: Balanced

Comment thread pnpm-workspace.yaml
Comment thread packages/babel/package.json
Comment thread packages/html/test/snapshots/test.js.snap Outdated
Wrap the root lockfile guard in a try/finally so the fixture cleanup
also runs when the guard detects a modified lockfile. Otherwise,
leftover files could make subsequent local runs pass vacuously.
Resolve virtual's typescript devDependency via the pnpm catalog to
get a current TypeScript version. This allows the types test to
provide the disposable lib that the rollup type declarations require
and to enable lib checks again instead of skipping them on older
TypeScript versions.
Since rollup 4.8.0, a dynamically imported module that tree-shakes to
an empty namespace when the import result is unused is inlined into
the importing chunk, which made the dynamic_imports_not_loaded test
vacuous at the development rollup version. Dynamically import a
fixture with a side effect so that a separate chunk is emitted and
excluded from the HTML in all supported rollup versions, and update
the shared snapshot and the earliest fork.
Nothing references the legacy html test.js.md, and its content still
describes the snapshot state before the dynamic import fixture was
changed. Also add the snapshots-earliest directories to
.prettierignore to mirror the ignored snapshots directories.
The callback-based copy was not awaited, so on slow CI runners it
could fire after the next test had changed the working directory,
resolving the relative paths against the wrong directory and failing
the run with an unhandled error.
@lukastaegert lukastaegert changed the title test(repo): test against the earliest supported rollup test(repo): test all packages against their earliest supported rollup versions Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants