In browser builds, if a plugin returns the result of this.resolve(..., { skipSelf: true }) from resolveId, an import that should be disabled via browser: false is instead resolved to the package directory and later fails to load.
Reproduction link or steps
Minimal repro:
package.json
{
"private": true,
"type": "module",
"scripts": {
"build": "rolldown -c rolldown.config.mjs"
},
"devDependencies": {
"rolldown": "1.0.0-rc.12"
}
}
src/main.js
import "../demo/index.js";
demo/package.json
{
"name": "demo",
"type": "module",
"browser": {
"buffer": false
}
}
demo/index.js
rolldown.config.mjs
export default {
input: "./src/main.js",
platform: "browser",
plugins: [
{
name: "probe",
async resolveId(id, importer, options) {
if (options?.isEntry || !id || id.startsWith(".") || id.startsWith("/")) {
return null;
}
const resolved = await this.resolve(id, importer, {
...options,
skipSelf: true,
});
console.log(id, resolved);
return resolved ?? null;
},
},
],
};
Run:
npm install
npm run build
Control:
- If
return resolved ?? null is changed to return null, the build succeeds.
What is expected?
Returning the result of this.resolve() from resolveId should preserve browser: false handling.
In this repro, import "buffer" inside demo/index.js should remain disabled/ignored for the browser build rather than being turned into a loadable module path.
What is actually happening?
The build fails with:
[UNLOADABLE_DEPENDENCY] Error: Could not load demo
demo/index.js:1:8
import "buffer";
^^^^^^^^
Is a directory (os error 21)
The logged resolution for buffer points at the package directory instead of preserving the browser: false result. Rolldown later tries to load that directory as a module and fails with Is a directory.
System Info
System:
OS: macOS 26.4
CPU: (12) arm64 Apple M4 Pro
Memory: 1020.94 MB / 24.00 GB
Shell: 4.6.0 - /opt/homebrew/bin/fish
Binaries:
Node: 24.14.1 - /Users/akolberg/.local/share/mise/installs/node/24.14.1/bin/node
Yarn: 4.13.0 - /Users/akolberg/.local/share/mise/installs/yarn/4.13.0/bin/yarn
npm: 11.11.0 - /Users/akolberg/.local/share/mise/installs/node/24.14.1/bin/npm
pnpm: 10.29.3 - /Users/akolberg/.local/share/mise/installs/pnpm/10.29.3/pnpm
bun: 1.3.9 - /Users/akolberg/.local/share/mise/installs/bun/1.3.9/bin/bun
Deno: 2.7.11 - /opt/homebrew/bin/deno
Browsers:
Chrome: 147.0.7727.56
Firefox: 149.0.2
Safari: 26.4
npmPackages:
rolldown: 1.0.0-rc.12 => 1.0.0-rc.12
In browser builds, if a plugin returns the result of
this.resolve(..., { skipSelf: true })fromresolveId, an import that should be disabled viabrowser: falseis instead resolved to the package directory and later fails to load.Reproduction link or steps
Minimal repro:
package.json{ "private": true, "type": "module", "scripts": { "build": "rolldown -c rolldown.config.mjs" }, "devDependencies": { "rolldown": "1.0.0-rc.12" } }src/main.jsdemo/package.json{ "name": "demo", "type": "module", "browser": { "buffer": false } }demo/index.jsrolldown.config.mjsRun:
Control:
return resolved ?? nullis changed toreturn null, the build succeeds.What is expected?
Returning the result of
this.resolve()fromresolveIdshould preservebrowser: falsehandling.In this repro,
import "buffer"insidedemo/index.jsshould remain disabled/ignored for the browser build rather than being turned into a loadable module path.What is actually happening?
The build fails with:
The logged resolution for
bufferpoints at the package directory instead of preserving thebrowser: falseresult. Rolldown later tries to load that directory as a module and fails withIs a directory.System Info
System: OS: macOS 26.4 CPU: (12) arm64 Apple M4 Pro Memory: 1020.94 MB / 24.00 GB Shell: 4.6.0 - /opt/homebrew/bin/fish Binaries: Node: 24.14.1 - /Users/akolberg/.local/share/mise/installs/node/24.14.1/bin/node Yarn: 4.13.0 - /Users/akolberg/.local/share/mise/installs/yarn/4.13.0/bin/yarn npm: 11.11.0 - /Users/akolberg/.local/share/mise/installs/node/24.14.1/bin/npm pnpm: 10.29.3 - /Users/akolberg/.local/share/mise/installs/pnpm/10.29.3/pnpm bun: 1.3.9 - /Users/akolberg/.local/share/mise/installs/bun/1.3.9/bin/bun Deno: 2.7.11 - /opt/homebrew/bin/deno Browsers: Chrome: 147.0.7727.56 Firefox: 149.0.2 Safari: 26.4 npmPackages: rolldown: 1.0.0-rc.12 => 1.0.0-rc.12