mirror of
https://github.com/hanzoai/esbuild.git
synced 2026-09-24 16:58:50 +00:00
fix #3001: EINVAL => ENOTDIR for readdir
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
* Work around an issue with `NODE_PATH` and Go's WebAssembly internals ([#3001](https://github.com/evanw/esbuild/issues/3001))
|
||||
|
||||
Go's WebAssembly implementation returns `EINVAL` instead of `ENOTDIR` when using the `readdir` syscall on a file. This messes up esbuild's implementation of node's module resolution algorithm since encountering `ENOTDIR` causes esbuild to continue its search (since it's a normal condition) while other encountering other errors causes esbuild to fail with an I/O error (since it's an unexpected condition). You can encounter this issue in practice if you use node's legacy `NODE_PATH` feature to tell esbuild to resolve node modules in a custom directory that was not installed by npm. This release works around this problem by converting `EINVAL` into `ENOTDIR` for the `readdir` syscall.
|
||||
|
||||
## 0.17.12
|
||||
|
||||
* Fix a crash when parsing inline TypeScript decorators ([#2991](https://github.com/evanw/esbuild/issues/2991))
|
||||
|
||||
@@ -360,6 +360,14 @@ func (fs *realFS) readdir(dirname string) (entries []string, canonicalError erro
|
||||
// Don't convert ENOTDIR to ENOENT here. ENOTDIR is a legitimate error
|
||||
// condition for Readdirnames() on non-Windows platforms.
|
||||
|
||||
// Go's WebAssembly implementation returns EINVAL instead of ENOTDIR if we
|
||||
// call "readdir" on a file. Canonicalize this to ENOTDIR so esbuild's path
|
||||
// resolution code continues traversing instead of failing with an error.
|
||||
// https://github.com/golang/go/blob/2449bbb5e614954ce9e99c8a481ea2ee73d72d61/src/syscall/fs_js.go#L144
|
||||
if pathErr, ok := canonicalError.(*os.PathError); ok && pathErr.Unwrap() == syscall.EINVAL {
|
||||
canonicalError = syscall.ENOTDIR
|
||||
}
|
||||
|
||||
return entries, canonicalError, originalError
|
||||
}
|
||||
|
||||
|
||||
@@ -324,6 +324,26 @@ const tests = {
|
||||
})();
|
||||
`)
|
||||
},
|
||||
|
||||
// https://github.com/evanw/esbuild/issues/3001
|
||||
nodePathsReaddirEINVAL({ testDir, esbuildPathWASM }) {
|
||||
const libDir = path.join(testDir, 'lib');
|
||||
const libFile = path.join(libDir, 'file.js');
|
||||
fs.mkdirSync(libDir, { recursive: true });
|
||||
fs.writeFileSync(libFile, 'foo()');
|
||||
const stdout = child_process.execFileSync('node', [
|
||||
esbuildPathWASM,
|
||||
'--bundle',
|
||||
'--format=esm',
|
||||
], {
|
||||
stdio: ['pipe', 'pipe', 'inherit'],
|
||||
cwd: testDir,
|
||||
input: `import "file.js"`,
|
||||
env: { ...process.env, NODE_PATH: libDir },
|
||||
}).toString();
|
||||
|
||||
assert.deepStrictEqual(stdout, '// lib/file.js\nfoo();\n');
|
||||
},
|
||||
};
|
||||
|
||||
function runTest({ testDir, esbuildPathNative, esbuildPathWASM, test }) {
|
||||
|
||||
Reference in New Issue
Block a user