diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 4654e677c0f694..12f44c8afe547f 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -557,7 +557,11 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { } // record as safe modules - server?.moduleGraph.safeModulesPath.add(fsPathFromUrl(url)) + // safeModulesPath should not include the base prefix. + // See https://github.com/vitejs/vite/issues/9438#issuecomment-1465270409 + server?.moduleGraph.safeModulesPath.add( + fsPathFromUrl(stripBase(url, base)), + ) if (url !== specifier) { let rewriteDone = false diff --git a/playground/fs-serve/__tests__/base/fs-serve-base.spec.ts b/playground/fs-serve/__tests__/base/fs-serve-base.spec.ts new file mode 100644 index 00000000000000..4660fafcc8031f --- /dev/null +++ b/playground/fs-serve/__tests__/base/fs-serve-base.spec.ts @@ -0,0 +1,104 @@ +import fetch from 'node-fetch' +import { beforeAll, describe, expect, test } from 'vitest' +import testJSON from '../../safe.json' +import { isServe, page, viteTestUrl } from '~utils' + +const stringified = JSON.stringify(testJSON) + +describe.runIf(isServe)('main', () => { + beforeAll(async () => { + const srcPrefix = viteTestUrl.endsWith('/') ? '' : '/' + await page.goto(viteTestUrl + srcPrefix + 'src/') + }) + + test('default import', async () => { + expect(await page.textContent('.full')).toBe(stringified) + }) + + test('named import', async () => { + expect(await page.textContent('.named')).toBe(testJSON.msg) + }) + + test('safe fetch', async () => { + expect(await page.textContent('.safe-fetch')).toMatch('KEY=safe') + expect(await page.textContent('.safe-fetch-status')).toBe('200') + }) + + test('safe fetch with query', async () => { + expect(await page.textContent('.safe-fetch-query')).toMatch('KEY=safe') + expect(await page.textContent('.safe-fetch-query-status')).toBe('200') + }) + + test('safe fetch with special characters', async () => { + expect( + await page.textContent('.safe-fetch-subdir-special-characters'), + ).toMatch('KEY=safe') + expect( + await page.textContent('.safe-fetch-subdir-special-characters-status'), + ).toBe('200') + }) + + test('unsafe fetch', async () => { + expect(await page.textContent('.unsafe-fetch')).toMatch('403 Restricted') + expect(await page.textContent('.unsafe-fetch-status')).toBe('403') + }) + + test('unsafe fetch with special characters (#8498)', async () => { + expect(await page.textContent('.unsafe-fetch-8498')).toBe('') + expect(await page.textContent('.unsafe-fetch-8498-status')).toBe('404') + }) + + test('unsafe fetch with special characters 2 (#8498)', async () => { + expect(await page.textContent('.unsafe-fetch-8498-2')).toBe('') + expect(await page.textContent('.unsafe-fetch-8498-2-status')).toBe('404') + }) + + test('safe fs fetch', async () => { + expect(await page.textContent('.safe-fs-fetch')).toBe(stringified) + expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') + }) + + test('safe fs fetch', async () => { + expect(await page.textContent('.safe-fs-fetch-query')).toBe(stringified) + expect(await page.textContent('.safe-fs-fetch-query-status')).toBe('200') + }) + + test('safe fs fetch with special characters', async () => { + expect(await page.textContent('.safe-fs-fetch-special-characters')).toBe( + stringified, + ) + expect( + await page.textContent('.safe-fs-fetch-special-characters-status'), + ).toBe('200') + }) + + test('unsafe fs fetch', async () => { + expect(await page.textContent('.unsafe-fs-fetch')).toBe('') + expect(await page.textContent('.unsafe-fs-fetch-status')).toBe('403') + }) + + test('unsafe fs fetch with special characters (#8498)', async () => { + expect(await page.textContent('.unsafe-fs-fetch-8498')).toBe('') + expect(await page.textContent('.unsafe-fs-fetch-8498-status')).toBe('404') + }) + + test('unsafe fs fetch with special characters 2 (#8498)', async () => { + expect(await page.textContent('.unsafe-fs-fetch-8498-2')).toBe('') + expect(await page.textContent('.unsafe-fs-fetch-8498-2-status')).toBe('404') + }) + + test('nested entry', async () => { + expect(await page.textContent('.nested-entry')).toBe('foobar') + }) + + test('denied', async () => { + expect(await page.textContent('.unsafe-dotenv')).toBe('404') + }) +}) + +describe('fetch', () => { + test('serve with configured headers', async () => { + const res = await fetch(viteTestUrl + '/src/') + expect(res.headers.get('x-served-by')).toBe('vite') + }) +}) diff --git a/playground/fs-serve/__tests__/fs-serve.spec.ts b/playground/fs-serve/__tests__/fs-serve.spec.ts index 8fab74d1bed7e3..86e030326ea420 100644 --- a/playground/fs-serve/__tests__/fs-serve.spec.ts +++ b/playground/fs-serve/__tests__/fs-serve.spec.ts @@ -7,7 +7,8 @@ const stringified = JSON.stringify(testJSON) describe.runIf(isServe)('main', () => { beforeAll(async () => { - await page.goto(viteTestUrl + '/src/') + const srcPrefix = viteTestUrl.endsWith('/') ? '' : '/' + await page.goto(viteTestUrl + srcPrefix + 'src/') }) test('default import', async () => { @@ -66,7 +67,9 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.safe-fs-fetch-special-characters')).toBe( stringified, ) - expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') + expect( + await page.textContent('.safe-fs-fetch-special-characters-status'), + ).toBe('200') }) test('unsafe fs fetch', async () => { @@ -88,10 +91,6 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.nested-entry')).toBe('foobar') }) - test('nested entry', async () => { - expect(await page.textContent('.nested-entry')).toBe('foobar') - }) - test('denied', async () => { expect(await page.textContent('.unsafe-dotenv')).toBe('404') }) diff --git a/playground/fs-serve/package.json b/playground/fs-serve/package.json index ceb4552d1c244f..b66b79268d8601 100644 --- a/playground/fs-serve/package.json +++ b/playground/fs-serve/package.json @@ -7,6 +7,9 @@ "dev": "vite root", "build": "vite build root", "debug": "node --inspect-brk ../../packages/vite/bin/vite", - "preview": "vite preview root" + "preview": "vite preview root", + "dev:base": "vite root --config ./root/vite.config-base.js", + "build:base": "vite build root --config ./root/vite.config-base.js", + "preview:base": "vite preview root --config ./root/vite.config-base.js" } } diff --git a/playground/fs-serve/root/src/index.html b/playground/fs-serve/root/src/index.html index 9e9cfe501d10fe..5de6804a7658de 100644 --- a/playground/fs-serve/root/src/index.html +++ b/playground/fs-serve/root/src/index.html @@ -50,11 +50,26 @@