Environment
Node.js: 20.11.1 and 24.8.0 (latest 24)
esbuild: 0.25.8 and 0.25.10 (latest)
postcss: 8.4.47 and 8.5.6 (latest)
Reproduction
Run npm install esbuild unplugin postcss.
Write the build script using esbuild, namely build.mjs.
import { build } from 'esbuild';
import { createUnplugin } from 'unplugin';
const plugin = createUnplugin(() => ({
name: 'passthru',
transform: {
handler(code) {
return { code };
}
}
}));
build({
bundle: true,
entryPoints: ['./index.ts'],
platform: 'browser',
plugins: [plugin.esbuild()]
});
Write the entry point file, namely index.ts.
import 'postcss/lib/input';
Then, run the build script, node ./build.mjs. It will error out.
✘ [ERROR] ENOENT: no such file or directory, open '/workspaces/.../node_modules/postcss/lib/terminal-highlight' [plugin passthru]
node_modules/esbuild/lib/main.js:1267:21:
1267 │ let result = await callback({
╵ ^
at async open (node:internal/fs/promises:642:25)
at async Object.readFile (node:internal/fs/promises:1279:14)
at async Object.getContents (file:///workspaces/.../node_modules/unplugin/dist/index.js:1070:34)
at async file:///workspaces/.../node_modules/unplugin/dist/index.js:1172:16
at async file:///workspaces/.../node_modules/unplugin/dist/index.js:1073:23
at async requestCallbacks.on-load (/workspaces/.../node_modules/esbuild/lib/main.js:1267:22)
at async handleRequest (/workspaces/.../node_modules/esbuild/lib/main.js:628:11)
Describe the bug
Oneliner: esbuild/unplugin trying to load packages with some files turned off via package.json/browser, esbuild send a extension-less args.path to unplugin, and unplugin failed to read the file via fs.readFile. postcss is one of the packages with "turned off" files.
In postcss/package.json, it has browser field to "turn off" some files. Excerpt:
{
"browser": {
"./lib/terminal-highlight": false,
"source-map-js": false,
"path": false,
"url": false,
"fs": false
}
}
unplugin trying to load postcss/lib/terminal-highlight as instructed by esbuild. However, the terminal-highlight file is "turned off" in the package.json.
esbuild sends the following args object to unplugin, and unplugin try to load it via fs.promises.readFile (Code):
{
path: '/workspaces/BotFramework-WebChat/node_modules/postcss/lib/terminal-highlight',
namespace: 'file',
suffix: '',
pluginData: undefined,
with: {}
}
The args.path does not contains any file extension because the file is "turned off" in package.json.
unplugin failed to load the file, resulting in an error and bubbled up.
Additional context
The scenario is specific to how unplugin load a file.
esbuild do not have a way for plugin to "request esbuild to load a file". So most esbuild plugins will try to load files themselves. Plugins which do this should be careful about esbuild not sending the file extension for files in some cases.
Logs
Environment
Node.js: 20.11.1 and 24.8.0 (latest 24)
esbuild: 0.25.8 and 0.25.10 (latest)
postcss: 8.4.47 and 8.5.6 (latest)
Reproduction
Run
npm install esbuild unplugin postcss.Write the build script using esbuild, namely
build.mjs.Write the entry point file, namely
index.ts.Then, run the build script,
node ./build.mjs. It will error out.Describe the bug
Oneliner: esbuild/unplugin trying to load packages with some files turned off via
package.json/browser, esbuild send a extension-lessargs.pathto unplugin, and unplugin failed to read the file viafs.readFile.postcssis one of the packages with "turned off" files.In
postcss/package.json, it hasbrowserfield to "turn off" some files. Excerpt:{ "browser": { "./lib/terminal-highlight": false, "source-map-js": false, "path": false, "url": false, "fs": false } }unplugin trying to load
postcss/lib/terminal-highlightas instructed byesbuild. However, theterminal-highlightfile is "turned off" in thepackage.json.esbuild sends the following
argsobject to unplugin, and unplugin try to load it viafs.promises.readFile(Code):The
args.pathdoes not contains any file extension because the file is "turned off" inpackage.json.unplugin failed to load the file, resulting in an error and bubbled up.
Additional context
The scenario is specific to how unplugin load a file.
esbuild do not have a way for plugin to "request esbuild to load a file". So most esbuild plugins will try to load files themselves. Plugins which do this should be careful about esbuild not sending the file extension for files in some cases.
Logs