diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts
index bf8c6337f8bc49..fa2dd4167fce5d 100644
--- a/packages/vite/src/node/server/pluginContainer.ts
+++ b/packages/vite/src/node/server/pluginContainer.ts
@@ -586,7 +586,20 @@ export async function createPluginContainer(
break
}
if (!combinedMap) {
- combinedMap = m as SourceMap
+ const sm = m as SourceMap
+ // sourcemap should not include `sources: [null]` (because `sources` should be string) nor
+ // `sources: ['']` (because `''` means the path of sourcemap)
+ // but MagicString generates this when `filename` option is not set.
+ // Rollup supports these and therefore we support this as well
+ if (sm.sources.length === 1 && !sm.sources[0]) {
+ combinedMap = {
+ ...sm,
+ sources: [this.filename],
+ sourcesContent: [this.originalCode],
+ }
+ } else {
+ combinedMap = sm
+ }
} else {
combinedMap = combineSourcemaps(cleanUrl(this.filename), [
m as RawSourceMap,
diff --git a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts
index b4e63e66290a74..208213d3d84f9e 100644
--- a/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts
+++ b/playground/js-sourcemap/__tests__/js-sourcemap.spec.ts
@@ -31,6 +31,27 @@ if (!isBuild) {
`)
})
+ test('plugin return sourcemap with `sources: [""]`', async () => {
+ const res = await page.request.get(new URL('./zoo.js', page.url()).href)
+ const js = await res.text()
+ expect(js).toContain('// add comment')
+
+ const map = extractSourcemap(js)
+ expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
+ {
+ "mappings": "AAAA,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;",
+ "sources": [
+ "zoo.js",
+ ],
+ "sourcesContent": [
+ "export const zoo = 'zoo'
+ ",
+ ],
+ "version": 3,
+ }
+ `)
+ })
+
test('js with inline sourcemap injected by a plugin', async () => {
const res = await page.request.get(
new URL('./foo-with-sourcemap.js', page.url()).href,
diff --git a/playground/js-sourcemap/index.html b/playground/js-sourcemap/index.html
index f669bf4fc102aa..80ee729d99ce90 100644
--- a/playground/js-sourcemap/index.html
+++ b/playground/js-sourcemap/index.html
@@ -7,3 +7,4 @@
JS Sourcemap
+
diff --git a/playground/js-sourcemap/package.json b/playground/js-sourcemap/package.json
index b002697756a24c..816f80c600f51c 100644
--- a/playground/js-sourcemap/package.json
+++ b/playground/js-sourcemap/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
- "@vitejs/test-importee-pkg": "file:importee-pkg"
+ "@vitejs/test-importee-pkg": "file:importee-pkg",
+ "magic-string": "^0.30.5"
}
}
diff --git a/playground/js-sourcemap/plugin-foo.js b/playground/js-sourcemap/plugin-foo.js
new file mode 100644
index 00000000000000..cb356468240d50
--- /dev/null
+++ b/playground/js-sourcemap/plugin-foo.js
@@ -0,0 +1 @@
+export const foo = 'foo'
diff --git a/playground/js-sourcemap/vite.config.js b/playground/js-sourcemap/vite.config.js
index efebbc5ca00dee..41484f2c99d0f3 100644
--- a/playground/js-sourcemap/vite.config.js
+++ b/playground/js-sourcemap/vite.config.js
@@ -1,8 +1,12 @@
import { defineConfig } from 'vite'
import transformFooWithInlineSourceMap from './foo-with-sourcemap-plugin'
+import { transformZooWithSourcemapPlugin } from './zoo-with-sourcemap-plugin'
export default defineConfig({
- plugins: [transformFooWithInlineSourceMap()],
+ plugins: [
+ transformFooWithInlineSourceMap(),
+ transformZooWithSourcemapPlugin(),
+ ],
build: {
sourcemap: true,
rollupOptions: {
diff --git a/playground/js-sourcemap/zoo-with-sourcemap-plugin.ts b/playground/js-sourcemap/zoo-with-sourcemap-plugin.ts
new file mode 100644
index 00000000000000..6c493278d166c8
--- /dev/null
+++ b/playground/js-sourcemap/zoo-with-sourcemap-plugin.ts
@@ -0,0 +1,18 @@
+import MagicString from 'magic-string'
+import type { Plugin } from 'vite'
+
+export const transformZooWithSourcemapPlugin: () => Plugin = () => ({
+ name: 'sourcemap',
+ transform(code, id) {
+ if (id.includes('zoo.js')) {
+ const ms = new MagicString(code)
+ ms.append('// add comment')
+ return {
+ code: ms.toString(),
+ // NOTE: MagicString without `filename` option generates
+ // a sourcemap with `sources: ['']` or `sources: [null]`
+ map: ms.generateMap({ hires: true }),
+ }
+ }
+ },
+})
diff --git a/playground/js-sourcemap/zoo.js b/playground/js-sourcemap/zoo.js
new file mode 100644
index 00000000000000..286343f930d3c3
--- /dev/null
+++ b/playground/js-sourcemap/zoo.js
@@ -0,0 +1 @@
+export const zoo = 'zoo'
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 22890b58e65a64..6c0b64a28ba8d8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -697,6 +697,9 @@ importers:
'@vitejs/test-importee-pkg':
specifier: file:importee-pkg
version: file:playground/js-sourcemap/importee-pkg
+ magic-string:
+ specifier: ^0.30.5
+ version: 0.30.5
playground/js-sourcemap/importee-pkg: {}