-
-
Notifications
You must be signed in to change notification settings - Fork 19
CJS plugin hooks (resolveId, load, transform) not applied to new Worker() sub-bundles #610
Description
Describe the bug
Bug: Plugin hooks (resolveId, load, transform) not applied to new Worker() sub-bundles
Description
When a project uses
new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }), Vite
8/Rolldown builds the worker as a separate sub-bundle. Plugin hooks
(resolveId, load, transform) registered in vite.config.js are silently
skipped for that sub-bundle. Hooks fire correctly in the main bundle but not in
worker bundles.
This surfaces as an unrecoverable CJS↔ESM interop regression:
Rolldown now resolves JSON files as ESM (export default [...]). When legacy
CJS code calls require('some-package') and that package does
module.exports = require('./data.json'), Rolldown's interop helper returns a
namespace object { __esModule: true, default: [...] } instead of the raw
array. This is a behavioral regression from Vite 7 / Rollup. The only
userland fix is a plugin hook — which doesn't reach the worker.
Workaround
resolve.alias is applied at the Rolldown config level and does reach worker
sub-bundles. Generate a .cjs shim at config-load time and alias the package to
it:
// vite.config.js
import path from "path";
import fs from "node:fs";
const shimDir = path.resolve(process.cwd(), "src/shims");
const osmShim = path.join(shimDir, "osm-polygon-features.cjs");
fs.mkdirSync(shimDir, { recursive: true });
fs.writeFileSync(
osmShim,
"module.exports = " +
fs.readFileSync(
path.resolve(
process.cwd(),
"node_modules/osm-polygon-features/polygon-features.json",
),
"utf-8",
) + ";\n",
);
export default defineConfig({
resolve: {
alias: {
"osm-polygon-features": osmShim,
},
},
});With this alias in place the worker bundle contains:
// In worker bundle — fixed
Bo = Ae(((e, t) => {
t.exports = [{ key: "building", polygon: "all" }, ...] // raw array, forEach works
}))Additional context
osm-polygon-featuresis also consumed byoverpass-frontend,
osm-polygon-features-extended, and any other library wrapping
osmtogeojson, so this affects a broad set of OSM tooling.- The two issues (plugin hooks skipped for workers; JSON→namespace regression)
may have the same underlying cause in Rolldown's worker build pipeline, or may
be separate. Fixing either one would unblock userland.
Reproduction
https://stackblitz.com/edit/vitejs-rolldown-vite-ipktsxdp?file=package.json
Steps to reproduce
Reproduction
Packages involved:
osmtogeojson@3.0.0-beta.5(CJS) — used inside anew Worker()osm-polygon-features@0.9.2(CJS, JSON re-export) — dependency of
osmtogeojson
osmtogeojson/index.js:
require("osm-polygon-features").forEach(function(tags) { ... });osm-polygon-features/index.js:
module.exports = require("./polygon-features.json");Steps:
-
Import
osmtogeojsoninside a Worker module:// myWorker.js import osmtogeojson from "osmtogeojson"; // ...
// main app new Worker(new URL("./myWorker.js", import.meta.url), { type: "module" });
-
Register a plugin in
vite.config.jsto interceptosm-polygon-featuresand
return it as a proper CJS module:{ name: 'fix-osm-polygon-features', enforce: 'pre', resolveId(id) { if (id === 'osm-polygon-features') return '\0virtual:osm-polygon-features'; }, load(id) { if (id === '\0virtual:osm-polygon-features') { const data = fs.readFileSync('node_modules/osm-polygon-features/polygon-features.json', 'utf-8'); return `module.exports = ${data};`; } } }
-
Run
vite build.
Result: The plugin hook fires for the main bundle. It does not fire for
the worker sub-bundle. The worker crashes at runtime:
Uncaught TypeError: jo(...).forEach is not a function
at osmParserWorker-XXX.js:3369
Inspecting the built worker bundle confirms the interop wrapper still wraps the
JSON as a namespace object:
// In worker bundle — broken
jo = Te((e, t) => {
t.exports = (Jo(), rs(Ho)); // rs() returns { __esModule: true, default: [...] }
});Expected behaviour
-
Plugin hooks (
resolveId,load,transform) should be invoked for all
modules resolved in worker sub-bundles, consistent with Vite 7/Rollup
behaviour. -
(Separate but related)
require()of a CJS module whose only export is a
JSON file should return the parsed value directly, not a namespace object.
This was the Rollup/Vite 7 behaviour and is what downstream CJS consumers
expect.
System Info
**Vite version:** `8.0.0-beta.18`\
**Rolldown version:** `1.0.0-rc.8`\
**OS:** Windows 11\
**Node:** `v22.22.1`
Error:
// In worker bundle — broken
jo = Te(((e, t) => {
t.exports = (Jo(), rs(Ho)); // rs() returns { __esModule: true, default: [...] }
}))Used Package Manager
npm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs and the Rolldown-related guide.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.