diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 34ede1f5be2303..24d5a0205d58c5 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -1,3 +1,4 @@ +import fs from 'node:fs' import { describe, expect, test } from 'vitest' import { asyncFlatten, @@ -5,6 +6,7 @@ import { getLocalhostAddressIfDiffersFromDNS, getPotentialTsSrcPaths, injectQuery, + isFileReadable, isWindows, posToNumber, resolveHostname @@ -236,3 +238,28 @@ describe('asyncFlatten', () => { expect(arr).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]) }) }) + +describe('isFileReadable', () => { + test("file doesn't exist", async () => { + expect(isFileReadable('/does_not_exist')).toBe(false) + }) + + const testFile = require.resolve( + './utils/isFileReadable/permission-test-file' + ) + test('file with normal permission', async () => { + expect(isFileReadable(testFile)).toBe(true) + }) + + if (process.platform !== 'win32') { + test('file with read-only permission', async () => { + fs.chmodSync(testFile, '400') + expect(isFileReadable(testFile)).toBe(true) + }) + test('file without read permission', async () => { + fs.chmodSync(testFile, '044') + expect(isFileReadable(testFile)).toBe(false) + fs.chmodSync(testFile, '644') + }) + } +}) diff --git a/packages/vite/src/node/__tests__/utils/isFileReadable/permission-test-file b/packages/vite/src/node/__tests__/utils/isFileReadable/permission-test-file new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index fcbd7644b6d857..cbe3ff26f3c5a7 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -531,9 +531,6 @@ function tryResolveFile( tryPrefix?: string, skipPackageJson?: boolean ): string | undefined { - // #2051 if we don't have read permission on a directory, existsSync() still - // works and will result in massively slow subsequent checks (which are - // unnecessary in the first place) if (isFileReadable(file)) { if (!fs.statSync(file).isDirectory()) { return getRealPath(file, options.preserveSymlinks) + postfix diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index f8aab87a13d96b..6e395d98b61140 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -535,16 +535,10 @@ export function writeFile( fs.writeFileSync(filename, content) } -/** - * Use fs.statSync(filename) instead of fs.existsSync(filename) - * #2051 if we don't have read permission on a directory, existsSync() still - * works and will result in massively slow subsequent checks (which are - * unnecessary in the first place) - */ export function isFileReadable(filename: string): boolean { try { - const stat = fs.statSync(filename, { throwIfNoEntry: false }) - return !!stat + fs.accessSync(filename, fs.constants.R_OK) + return true } catch { return false }