Repository navigation
test(repo): test all packages against their earliest supported rollup versions - #2035
Open
lukastaegert wants to merge 43 commits into
Open
lukastaegert wants to merge 43 commits into
lukastaegert wants to merge 43 commits into
Conversation
…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
force-pushed
the
test-earliest-supported-rollup
branch
from
October 27, 2026 15:33
fc1203f to
116b199
Compare
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
force-pushed
the
test-earliest-supported-rollup
branch
from
October 27, 2026 15:57
00d1d4a to
f79b4a2
Compare
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
marked this pull request as ready for review
October 27, 2026 17:38
lukastaegert
requested review from
Andarist,
shellscape,
tada5hi and
tjenkinson
as code owners
October 27, 2026 17:38
[Medium impact] The PR appears safe to merge; no new blocking issues were found.
|
There was a problem hiding this comment.
🟡 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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Rollup Plugin Name:
allThis PR contains:
Are tests included?
Breaking Changes?
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-earliestto 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:
Let me know what you think, and if we should change anything about the current pull request.
Findings from this PR:
@rollup/plugin-htmlis pinned to 1.21.0 instead of its declared floor1.20.0: the plugin's entry detection relies on the bundle file
typeproperty, 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.
@rollup/plugin-auto-installtests through a pnpm script putsthe workspace-level
node_modules/.binintoPATH, so the package installsspawned 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
PATHfor their duration and assert the rootlockfile 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.
@rollup/plugin-babelis 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.