diff --git a/packages/compiler-sfc/__tests__/compileScript.spec.ts b/packages/compiler-sfc/__tests__/compileScript.spec.ts
index 11b5661c16c..73c6d316a40 100644
--- a/packages/compiler-sfc/__tests__/compileScript.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript.spec.ts
@@ -1,5 +1,11 @@
import { BindingTypes } from '@vue/compiler-core'
-import { assertCode, compileSFCScript as compile, mockId } from './utils'
+import {
+ assertCode,
+ compileSFCScript as compile,
+ getPositionInCode,
+ mockId,
+} from './utils'
+import { type RawSourceMap, SourceMapConsumer } from 'source-map-js'
describe('SFC compile
+
+
+
+ `
+ const { content, map } = compile(source, { inlineTemplate: true })
+ expect(map).not.toBeUndefined()
+ const consumer = new SourceMapConsumer(map as RawSourceMap)
+ expect(
+ consumer.originalPositionFor(getPositionInCode(content, 'count')),
+ ).toMatchObject(getPositionInCode(source, `count`))
+ expect(
+ consumer.originalPositionFor(getPositionInCode(content, 'Error')),
+ ).toMatchObject(getPositionInCode(source, `Error`))
+ })
})
describe('with TypeScript', () => {
diff --git a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
index 2ea1eb9d378..d4ddc763812 100644
--- a/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileTemplate.spec.ts
@@ -6,6 +6,7 @@ import {
} from '../src/compileTemplate'
import { type SFCTemplateBlock, parse } from '../src/parse'
import { compileScript } from '../src'
+import { getPositionInCode } from './utils'
function compile(opts: Omit) {
return compileTemplate({
@@ -482,36 +483,3 @@ test('non-identifier expression in legacy filter syntax', () => {
babelParse(compilationResult.code, { sourceType: 'module' })
}).not.toThrow()
})
-
-interface Pos {
- line: number
- column: number
- name?: string
-}
-
-function getPositionInCode(
- code: string,
- token: string,
- expectName: string | boolean = false,
-): Pos {
- const generatedOffset = code.indexOf(token)
- let line = 1
- let lastNewLinePos = -1
- for (let i = 0; i < generatedOffset; i++) {
- if (code.charCodeAt(i) === 10 /* newline char code */) {
- line++
- lastNewLinePos = i
- }
- }
- const res: Pos = {
- line,
- column:
- lastNewLinePos === -1
- ? generatedOffset
- : generatedOffset - lastNewLinePos - 1,
- }
- if (expectName) {
- res.name = typeof expectName === 'string' ? expectName : token
- }
- return res
-}
diff --git a/packages/compiler-sfc/__tests__/utils.ts b/packages/compiler-sfc/__tests__/utils.ts
index 5a58a6b58ae..b5cfc9606d5 100644
--- a/packages/compiler-sfc/__tests__/utils.ts
+++ b/packages/compiler-sfc/__tests__/utils.ts
@@ -40,3 +40,36 @@ export function assertCode(code: string): void {
}
expect(code).toMatchSnapshot()
}
+
+interface Pos {
+ line: number
+ column: number
+ name?: string
+}
+
+export function getPositionInCode(
+ code: string,
+ token: string,
+ expectName: string | boolean = false,
+): Pos {
+ const generatedOffset = code.indexOf(token)
+ let line = 1
+ let lastNewLinePos = -1
+ for (let i = 0; i < generatedOffset; i++) {
+ if (code.charCodeAt(i) === 10 /* newline char code */) {
+ line++
+ lastNewLinePos = i
+ }
+ }
+ const res: Pos = {
+ line,
+ column:
+ lastNewLinePos === -1
+ ? generatedOffset
+ : generatedOffset - lastNewLinePos - 1,
+ }
+ if (expectName) {
+ res.name = typeof expectName === 'string' ? expectName : token
+ }
+ return res
+}
diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts
index 8098b43ce45..67af92df5e7 100644
--- a/packages/compiler-sfc/src/compileScript.ts
+++ b/packages/compiler-sfc/src/compileScript.ts
@@ -23,7 +23,11 @@ import type {
Statement,
} from '@babel/types'
import { walk } from 'estree-walker'
-import type { RawSourceMap } from 'source-map-js'
+import {
+ type RawSourceMap,
+ SourceMapConsumer,
+ SourceMapGenerator,
+} from 'source-map-js'
import {
normalScriptDefaultVar,
processNormalScript,
@@ -32,7 +36,6 @@ import { CSS_VARS_HELPER, genCssVarsCode } from './style/cssVars'
import {
type SFCTemplateCompileOptions,
compileTemplate,
- mergeSourceMaps,
} from './compileTemplate'
import { warnOnce } from './warn'
import { transformDestructuredProps } from './script/definePropsDestructure'
@@ -1034,10 +1037,12 @@ export function compileScript(
includeContent: true,
}) as unknown as RawSourceMap)
: undefined
- if (map && templateMap) {
+ // merge source maps of the script setup and template in inline mode
+ if (templateMap && map) {
const offset = content.indexOf(returned)
- const lineOffset = content.slice(0, offset).split(/\r?\n/).length - 1
- map = mergeSourceMaps(map, templateMap, lineOffset)
+ const templateLineOffset =
+ content.slice(0, offset).split(/\r?\n/).length - 1
+ map = mergeSourceMaps(map, templateMap, templateLineOffset)
}
return {
...scriptSetup,
@@ -1301,3 +1306,42 @@ function isStaticNode(node: Node): boolean {
}
return false
}
+
+export function mergeSourceMaps(
+ scriptMap: RawSourceMap,
+ templateMap: RawSourceMap,
+ templateLineOffset: number,
+): RawSourceMap {
+ const generator = new SourceMapGenerator()
+ const addMapping = (map: RawSourceMap, lineOffset = 0) => {
+ const consumer = new SourceMapConsumer(map)
+ ;(consumer as any).sources.forEach((sourceFile: string) => {
+ ;(generator as any)._sources.add(sourceFile)
+ const sourceContent = consumer.sourceContentFor(sourceFile)
+ if (sourceContent != null) {
+ generator.setSourceContent(sourceFile, sourceContent)
+ }
+ })
+ consumer.eachMapping(m => {
+ if (m.originalLine == null) return
+ generator.addMapping({
+ generated: {
+ line: m.generatedLine + lineOffset,
+ column: m.generatedColumn,
+ },
+ original: {
+ line: m.originalLine,
+ column: m.originalColumn,
+ },
+ source: m.source,
+ name: m.name,
+ })
+ })
+ }
+
+ addMapping(scriptMap)
+ addMapping(templateMap, templateLineOffset)
+ ;(generator as any)._sourceRoot = scriptMap.sourceRoot
+ ;(generator as any)._file = scriptMap.file
+ return (generator as any).toJSON()
+}
diff --git a/packages/compiler-sfc/src/compileTemplate.ts b/packages/compiler-sfc/src/compileTemplate.ts
index 7c1d63ea1cb..322b1570e1a 100644
--- a/packages/compiler-sfc/src/compileTemplate.ts
+++ b/packages/compiler-sfc/src/compileTemplate.ts
@@ -327,51 +327,6 @@ function mapLines(oldMap: RawSourceMap, newMap: RawSourceMap): RawSourceMap {
return generator.toJSON()
}
-export function mergeSourceMaps(
- scriptMap: RawSourceMap,
- templateMap: RawSourceMap,
- templateLineOffset: number,
-): RawSourceMap {
- if (!templateMap) return scriptMap
- if (!scriptMap) return templateMap
-
- const mergedMapGenerator = new SourceMapGenerator() as any
- const scriptConsumer = new SourceMapConsumer(scriptMap)
- scriptConsumer.eachMapping(mapping => {
- if (mapping.originalLine == null) return
- mergedMapGenerator.addMapping({
- generated: {
- line: mapping.generatedLine,
- column: mapping.generatedColumn,
- },
- original: {
- line: mapping.originalLine,
- column: mapping.originalColumn,
- },
- source: mapping.source,
- name: mapping.name,
- })
- })
-
- const templateConsumer = new SourceMapConsumer(templateMap)
- templateConsumer.eachMapping(mapping => {
- if (mapping.originalLine == null) return
- mergedMapGenerator.addMapping({
- generated: {
- line: mapping.generatedLine + templateLineOffset,
- column: mapping.generatedColumn,
- },
- original: {
- line: mapping.originalLine,
- column: mapping.originalColumn,
- },
- source: mapping.source,
- name: mapping.name,
- })
- })
- return mergedMapGenerator.toJSON()
-}
-
function patchErrors(
errors: CompilerError[],
source: string,