From 1323fb6178726f978c5aae8274272f4bb8b0a1f8 Mon Sep 17 00:00:00 2001 From: semimikoh Date: Mon, 6 Apr 2026 12:36:42 +0900 Subject: [PATCH 1/3] fix: skip fallback sourcemap generation for ?raw imports --- .../src/node/server/__tests__/send.spec.ts | 66 +++++++++++++++++++ .../src/node/server/middlewares/transform.ts | 3 + packages/vite/src/node/server/send.ts | 8 ++- 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 packages/vite/src/node/server/__tests__/send.spec.ts diff --git a/packages/vite/src/node/server/__tests__/send.spec.ts b/packages/vite/src/node/server/__tests__/send.spec.ts new file mode 100644 index 00000000000000..0498861712ab07 --- /dev/null +++ b/packages/vite/src/node/server/__tests__/send.spec.ts @@ -0,0 +1,66 @@ +import type { IncomingMessage, ServerResponse } from 'node:http' +import { describe, expect, test } from 'vitest' +import { send } from '../send' + +interface MockResponse { + body?: string | Buffer + headers: Map + writableEnded: boolean + statusCode: number + setHeader(name: string, value: string | number | readonly string[]): void + end(content?: string | Buffer): void +} + +function createMockResponse(): MockResponse { + const headers = new Map() + + return { + headers, + writableEnded: false, + statusCode: 0, + setHeader(name: string, value: string | number | readonly string[]) { + headers.set(name.toLowerCase(), value) + }, + end(content?: string | Buffer) { + this.writableEnded = true + this.body = content + }, + } +} + +describe('send', () => { + test('injects fallback sourcemap for small js responses', () => { + const req = { + headers: {}, + method: 'GET', + url: '/test.js', + } as IncomingMessage + const res = createMockResponse() + + send( + req, + res as unknown as ServerResponse, + 'export const answer = 42', + 'js', + {}, + ) + + expect(res.body?.toString()).toContain('//# sourceMappingURL=') + }) + + test('skips fallback sourcemap when explicitly disabled', () => { + const req = { + headers: {}, + method: 'GET', + url: '/test.txt?import&raw', + } as IncomingMessage + const res = createMockResponse() + const code = `export default ${JSON.stringify('x\n'.repeat(600_000))}` + + send(req, res as unknown as ServerResponse, code, 'js', { + skipFallbackSourcemap: true, + }) + + expect(res.body?.toString()).toBe(code) + }) +}) diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index c6faf6fd7307c0..8a34f94ad9bc8e 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -266,6 +266,9 @@ export function transformMiddleware( cacheControl: isDep ? 'max-age=31536000,immutable' : 'no-cache', headers: server.config.server.headers, map: result.map, + // Raw imports already contain the final source text in the JS payload, + // so the fallback inline sourcemap duplicates large content with little value. + skipFallbackSourcemap: rawRE.test(url), }) } } diff --git a/packages/vite/src/node/server/send.ts b/packages/vite/src/node/server/send.ts index 780ab8984a6441..a0df2f445c7ded 100644 --- a/packages/vite/src/node/server/send.ts +++ b/packages/vite/src/node/server/send.ts @@ -27,6 +27,7 @@ export interface SendOptions { cacheControl?: string headers?: OutgoingHttpHeaders map?: SourceMap | { mappings: '' } | null + skipFallbackSourcemap?: boolean } export function send( @@ -41,6 +42,7 @@ export function send( cacheControl = 'no-cache', headers, map, + skipFallbackSourcemap = false, } = options if (res.writableEnded) { @@ -71,7 +73,11 @@ export function send( } // inject fallback sourcemap for js for improved debugging // https://github.com/vitejs/vite/pull/13514#issuecomment-1592431496 - else if (type === 'js' && (!map || map.mappings !== '')) { + else if ( + type === 'js' && + !skipFallbackSourcemap && + (!map || map.mappings !== '') + ) { const code = content.toString() // if the code has existing inline sourcemap, assume it's correct and skip if (convertSourceMap.mapFileCommentRegex.test(code)) { From 52f9c6daf4cf20ed86b5097f5778310f243f243a Mon Sep 17 00:00:00 2001 From: semimikoh Date: Mon, 13 Apr 2026 13:01:57 +0900 Subject: [PATCH 2/3] fix: use empty sourcemap to skip fallback sourcemap for ?raw imports --- packages/vite/src/node/plugins/asset.ts | 1 + packages/vite/src/node/server/__tests__/send.spec.ts | 4 ++-- packages/vite/src/node/server/middlewares/transform.ts | 3 --- packages/vite/src/node/server/send.ts | 8 +------- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index b5e2b652da3cbc..72326bd7c7698d 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -209,6 +209,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { code: `export default ${JSON.stringify( await fsp.readFile(file, 'utf-8'), )}`, + map: { mappings: '' }, moduleType: 'js', // NOTE: needs to be set to avoid double `export default` in `?raw&.txt`s } } diff --git a/packages/vite/src/node/server/__tests__/send.spec.ts b/packages/vite/src/node/server/__tests__/send.spec.ts index 0498861712ab07..6607e284acc442 100644 --- a/packages/vite/src/node/server/__tests__/send.spec.ts +++ b/packages/vite/src/node/server/__tests__/send.spec.ts @@ -48,7 +48,7 @@ describe('send', () => { expect(res.body?.toString()).toContain('//# sourceMappingURL=') }) - test('skips fallback sourcemap when explicitly disabled', () => { + test('skips fallback sourcemap when empty mappings are provided', () => { const req = { headers: {}, method: 'GET', @@ -58,7 +58,7 @@ describe('send', () => { const code = `export default ${JSON.stringify('x\n'.repeat(600_000))}` send(req, res as unknown as ServerResponse, code, 'js', { - skipFallbackSourcemap: true, + map: { mappings: '' }, }) expect(res.body?.toString()).toBe(code) diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index 8a34f94ad9bc8e..c6faf6fd7307c0 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -266,9 +266,6 @@ export function transformMiddleware( cacheControl: isDep ? 'max-age=31536000,immutable' : 'no-cache', headers: server.config.server.headers, map: result.map, - // Raw imports already contain the final source text in the JS payload, - // so the fallback inline sourcemap duplicates large content with little value. - skipFallbackSourcemap: rawRE.test(url), }) } } diff --git a/packages/vite/src/node/server/send.ts b/packages/vite/src/node/server/send.ts index a0df2f445c7ded..780ab8984a6441 100644 --- a/packages/vite/src/node/server/send.ts +++ b/packages/vite/src/node/server/send.ts @@ -27,7 +27,6 @@ export interface SendOptions { cacheControl?: string headers?: OutgoingHttpHeaders map?: SourceMap | { mappings: '' } | null - skipFallbackSourcemap?: boolean } export function send( @@ -42,7 +41,6 @@ export function send( cacheControl = 'no-cache', headers, map, - skipFallbackSourcemap = false, } = options if (res.writableEnded) { @@ -73,11 +71,7 @@ export function send( } // inject fallback sourcemap for js for improved debugging // https://github.com/vitejs/vite/pull/13514#issuecomment-1592431496 - else if ( - type === 'js' && - !skipFallbackSourcemap && - (!map || map.mappings !== '') - ) { + else if (type === 'js' && (!map || map.mappings !== '')) { const code = content.toString() // if the code has existing inline sourcemap, assume it's correct and skip if (convertSourceMap.mapFileCommentRegex.test(code)) { From 401b3c057b556f40cf4c0c7f077d641c17b358a9 Mon Sep 17 00:00:00 2001 From: semimikoh Date: Fri, 17 Apr 2026 15:56:27 +0900 Subject: [PATCH 3/3] fix: remove send.spec.ts per review feedback --- .../src/node/server/__tests__/send.spec.ts | 66 ------------------- 1 file changed, 66 deletions(-) delete mode 100644 packages/vite/src/node/server/__tests__/send.spec.ts diff --git a/packages/vite/src/node/server/__tests__/send.spec.ts b/packages/vite/src/node/server/__tests__/send.spec.ts deleted file mode 100644 index 6607e284acc442..00000000000000 --- a/packages/vite/src/node/server/__tests__/send.spec.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { IncomingMessage, ServerResponse } from 'node:http' -import { describe, expect, test } from 'vitest' -import { send } from '../send' - -interface MockResponse { - body?: string | Buffer - headers: Map - writableEnded: boolean - statusCode: number - setHeader(name: string, value: string | number | readonly string[]): void - end(content?: string | Buffer): void -} - -function createMockResponse(): MockResponse { - const headers = new Map() - - return { - headers, - writableEnded: false, - statusCode: 0, - setHeader(name: string, value: string | number | readonly string[]) { - headers.set(name.toLowerCase(), value) - }, - end(content?: string | Buffer) { - this.writableEnded = true - this.body = content - }, - } -} - -describe('send', () => { - test('injects fallback sourcemap for small js responses', () => { - const req = { - headers: {}, - method: 'GET', - url: '/test.js', - } as IncomingMessage - const res = createMockResponse() - - send( - req, - res as unknown as ServerResponse, - 'export const answer = 42', - 'js', - {}, - ) - - expect(res.body?.toString()).toContain('//# sourceMappingURL=') - }) - - test('skips fallback sourcemap when empty mappings are provided', () => { - const req = { - headers: {}, - method: 'GET', - url: '/test.txt?import&raw', - } as IncomingMessage - const res = createMockResponse() - const code = `export default ${JSON.stringify('x\n'.repeat(600_000))}` - - send(req, res as unknown as ServerResponse, code, 'js', { - map: { mappings: '' }, - }) - - expect(res.body?.toString()).toBe(code) - }) -})