-
Notifications
You must be signed in to change notification settings - Fork 142
Description
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.