From a64965383d78c78c169368785f365faa62c16c82 Mon Sep 17 00:00:00 2001 From: bluwy Date: Sun, 15 Oct 2023 02:23:44 +0800 Subject: [PATCH] fix(resolve): make directory package.json check best effort --- packages/vite/src/node/plugins/resolve.ts | 10 +++++++-- playground/resolve/__tests__/resolve.spec.ts | 22 +++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 2c89918968f981..60747049789f33 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -52,6 +52,8 @@ import { const normalizedClientEntry = normalizePath(CLIENT_ENTRY) const normalizedEnvEntry = normalizePath(ENV_ENTRY) +const ERR_RESOLVE_PACKAGE_ENTRY_FAIL = 'ERR_RESOLVE_PACKAGE_ENTRY_FAIL' + // special id for paths marked with browser: false // https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module export const browserExternalId = '__vite-browser-external' @@ -642,7 +644,9 @@ function tryCleanFsResolve( return resolvePackageEntry(dirPath, pkg, targetWeb, options) } } catch (e) { - if (e.code !== 'ENOENT') throw e + // This check is best effort, so if an entry is not found, skip error for now + if (e.code !== ERR_RESOLVE_PACKAGE_ENTRY_FAIL && e.code !== 'ENOENT') + throw e } } @@ -1101,11 +1105,13 @@ export function resolvePackageEntry( } function packageEntryFailure(id: string, details?: string) { - throw new Error( + const err: any = new Error( `Failed to resolve entry for package "${id}". ` + `The package may have incorrect main/module/exports specified in its package.json` + (details ? ': ' + details : '.'), ) + err.code = ERR_RESOLVE_PACKAGE_ENTRY_FAIL + throw err } function resolveExportsOrImports( diff --git a/playground/resolve/__tests__/resolve.spec.ts b/playground/resolve/__tests__/resolve.spec.ts index 4a753149552bf2..d5067698e13713 100644 --- a/playground/resolve/__tests__/resolve.spec.ts +++ b/playground/resolve/__tests__/resolve.spec.ts @@ -1,7 +1,8 @@ import fs from 'node:fs' import path from 'node:path' +import { fileURLToPath } from 'node:url' import { expect, test } from 'vitest' -import { isBuild, isWindows, page, testDir } from '~utils' +import { isBuild, isWindows, page, testDir, viteTestUrl } from '~utils' test('bom import', async () => { expect(await page.textContent('.utf8-bom')).toMatch('[success]') @@ -202,6 +203,25 @@ test('Resolving from other package with imports field', async () => { expect(await page.textContent('.imports-pkg-slash')).toMatch('[success]') }) +test('Resolve doesnt interrupt page request with trailing query and .css', async () => { + await page.goto(viteTestUrl + '/?test.css') + expect(await page.locator('vite-error-overlay').count()).toBe(0) + expect(await page.textContent('h1')).toBe('Resolve') +}) + +test.runIf(!isWindows)( + 'Resolve doesnt interrupt page request that clashes with local project package.json', + async () => { + // Sometimes request path may point to a different project's package.json, but for testing + // we point to Vite's own monorepo which always exists, and the package.json is not a library + const pathToViteMonorepoRoot = new URL('../../../', import.meta.url) + const urlPath = fileURLToPath(pathToViteMonorepoRoot).replace(/\/$/, '') + await page.goto(viteTestUrl + urlPath) + expect(await page.locator('vite-error-overlay').count()).toBe(0) + expect(await page.textContent('h1')).toBe('Resolve') + }, +) + test.runIf(isBuild)('public dir is not copied', async () => { expect( fs.existsSync(path.resolve(testDir, 'dist/should-not-be-copied')),