Skip to content

Commit

Permalink
fix(plugin-vue): fix sourcemap when no script block in sfc (close #8601
Browse files Browse the repository at this point in the history
…) (#8604)
  • Loading branch information
meteorlxy committed Jun 16, 2022
1 parent 2dd0b49 commit ccfccec
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 38 deletions.
82 changes: 44 additions & 38 deletions packages/plugin-vue/src/main.ts
@@ -1,6 +1,6 @@
import path from 'path'
import type { SFCBlock, SFCDescriptor } from 'vue/compiler-sfc'
import type { PluginContext, SourceMap, TransformPluginContext } from 'rollup'
import type { PluginContext, TransformPluginContext } from 'rollup'
import type { RawSourceMap } from 'source-map'
import type { EncodedSourceMap as TraceEncodedSourceMap } from '@jridgewell/trace-mapping'
import { TraceMap, eachMapping } from '@jridgewell/trace-mapping'
Expand Down Expand Up @@ -46,7 +46,7 @@ export async function transformMain(
const hasScoped = descriptor.styles.some((s) => s.scoped)

// script
const { code: scriptCode, map } = await genScriptCode(
const { code: scriptCode, map: scriptMap } = await genScriptCode(
descriptor,
options,
pluginContext,
Expand All @@ -58,7 +58,7 @@ export async function transformMain(
descriptor.template && !isUseInlineTemplate(descriptor, !devServer)

let templateCode = ''
let templateMap: RawSourceMap | undefined
let templateMap: RawSourceMap | undefined = undefined
if (hasTemplateImport) {
;({ code: templateCode, map: templateMap } = await genTemplateCode(
descriptor,
Expand Down Expand Up @@ -156,40 +156,46 @@ export async function transformMain(
)
}

// if the template is inlined into the main module (indicated by the presence
// of templateMap, we need to concatenate the two source maps.
let resolvedMap = options.sourceMap ? map : undefined
if (resolvedMap && templateMap) {
const gen = fromMap(
// version property of result.map is declared as string
// but actually it is `3`
map as Omit<RawSourceMap, 'version'> as TraceEncodedSourceMap
)
const tracer = new TraceMap(
// same above
templateMap as Omit<RawSourceMap, 'version'> as TraceEncodedSourceMap
)
const offset = (scriptCode.match(/\r?\n/g)?.length ?? 0) + 1
eachMapping(tracer, (m) => {
if (m.source == null) return
addMapping(gen, {
source: m.source,
original: { line: m.originalLine, column: m.originalColumn },
generated: {
line: m.generatedLine + offset,
column: m.generatedColumn
}
let resolvedMap: RawSourceMap | undefined = undefined
if (options.sourceMap) {
if (scriptMap && templateMap) {
// if the template is inlined into the main module (indicated by the presence
// of templateMap, we need to concatenate the two source maps.

const gen = fromMap(
// version property of result.map is declared as string
// but actually it is `3`
scriptMap as Omit<RawSourceMap, 'version'> as TraceEncodedSourceMap
)
const tracer = new TraceMap(
// same above
templateMap as Omit<RawSourceMap, 'version'> as TraceEncodedSourceMap
)
const offset = (scriptCode.match(/\r?\n/g)?.length ?? 0) + 1
eachMapping(tracer, (m) => {
if (m.source == null) return
addMapping(gen, {
source: m.source,
original: { line: m.originalLine, column: m.originalColumn },
generated: {
line: m.generatedLine + offset,
column: m.generatedColumn
}
})
})
})

// same above
resolvedMap = toEncodedMap(gen) as Omit<
GenEncodedSourceMap,
'version'
> as RawSourceMap
// if this is a template only update, we will be reusing a cached version
// of the main module compile result, which has outdated sourcesContent.
resolvedMap.sourcesContent = templateMap.sourcesContent
// same above
resolvedMap = toEncodedMap(gen) as Omit<
GenEncodedSourceMap,
'version'
> as RawSourceMap
// if this is a template only update, we will be reusing a cached version
// of the main module compile result, which has outdated sourcesContent.
resolvedMap.sourcesContent = templateMap.sourcesContent
} else {
// if one of `scriptMap` and `templateMap` is empty, use the other one
resolvedMap = scriptMap ?? templateMap
}
}

if (!attachedProps.length) {
Expand Down Expand Up @@ -287,10 +293,10 @@ async function genScriptCode(
ssr: boolean
): Promise<{
code: string
map: RawSourceMap
map: RawSourceMap | undefined
}> {
let scriptCode = `const _sfc_main = {}`
let map: RawSourceMap | SourceMap | undefined
let map: RawSourceMap | undefined

const script = resolveScript(descriptor, options, ssr)
if (script) {
Expand Down Expand Up @@ -322,7 +328,7 @@ async function genScriptCode(
}
return {
code: scriptCode,
map: map as any
map
}
}

Expand Down
4 changes: 4 additions & 0 deletions playground/vue-sourcemap/Main.vue
Expand Up @@ -7,6 +7,8 @@
<SassWithImport />
<Less />
<SrcImport />
<NoScript />
<NoTemplate />
</template>

<script setup lang="ts">
Expand All @@ -17,4 +19,6 @@ import Sass from './Sass.vue'
import SassWithImport from './SassWithImport.vue'
import Less from './Less.vue'
import SrcImport from './src-import/SrcImport.vue'
import NoScript from './NoScript.vue'
import NoTemplate from './NoTemplate.vue'
</script>
3 changes: 3 additions & 0 deletions playground/vue-sourcemap/NoScript.vue
@@ -0,0 +1,3 @@
<template>
<p>&lt;no-script&gt;</p>
</template>
7 changes: 7 additions & 0 deletions playground/vue-sourcemap/NoTemplate.vue
@@ -0,0 +1,7 @@
<script>
console.log('script')
</script>

<script setup>
console.log('setup')
</script>
50 changes: 50 additions & 0 deletions playground/vue-sourcemap/__tests__/serve.spec.ts
Expand Up @@ -334,4 +334,54 @@ describe.runIf(isServe)('serve:vue-sourcemap', () => {
}
`)
})

test('no script', async () => {
const res = await page.request.get(
new URL('./NoScript.vue', page.url()).href
)
const js = await res.text()
const map = extractSourcemap(js)
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
{
"mappings": ";;;wBACE",
"sources": [
"/root/NoScript.vue",
],
"sourcesContent": [
"<template>
<p>&lt;no-script&gt;</p>
</template>
",
],
"version": 3,
}
`)
})

test('no template', async () => {
const res = await page.request.get(
new URL('./NoTemplate.vue', page.url()).href
)
const js = await res.text()
const map = extractSourcemap(js)
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
{
"mappings": "2IACA,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;AAGP;AACd,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC",
"sources": [
"/root/NoTemplate.vue",
],
"sourcesContent": [
"<script>
console.log('script')
</script>
<script setup>
console.log('setup')
</script>
",
],
"version": 3,
}
`)
})
})

0 comments on commit ccfccec

Please sign in to comment.