Skip to content

Commit

Permalink
wip: should not reuse AST when using custom compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Nov 25, 2023
1 parent 3ee3439 commit 79d3cc6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
27 changes: 27 additions & 0 deletions packages/compiler-sfc/__tests__/compileTemplate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,33 @@ test('should work w/ AST from descriptor', () => {
).toMatchObject(getPositionInCode(source, `foobar`))
})

test('should not reuse AST if using custom compiler', () => {
const source = `
<template>
<div><p>{{ foobar }}</p></div>
</template>
`
const template = parse(source, {
filename: 'example.vue',
sourceMap: true
}).descriptor.template!

const { code } = compile({
filename: 'example.vue',
source: template.content,
ast: template.ast,
compiler: {
parse: () => null as any,
// @ts-ignore
compile: input => ({ code: input })
}
})

// what we really want to assert is that the `input` received by the custom
// compiler is the source string, not the AST.
expect(code).toBe(template.content)
})

test('template errors', () => {
const result = compile({
filename: 'example.vue',
Expand Down
16 changes: 13 additions & 3 deletions packages/compiler-sfc/src/compileTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ function doCompileTemplate({
ssr = false,
ssrCssVars,
isProd = false,
compiler = ssr ? (CompilerSSR as TemplateCompiler) : CompilerDOM,
compiler,
compilerOptions = {},
transformAssetUrls
}: SFCTemplateCompileOptions): SFCTemplateCompileResults {
Expand Down Expand Up @@ -205,9 +205,19 @@ function doCompileTemplate({
const shortId = id.replace(/^data-v-/, '')
const longId = `data-v-${shortId}`

const defaultCompiler = ssr ? (CompilerSSR as TemplateCompiler) : CompilerDOM
compiler = compiler || defaultCompiler

if (compiler !== defaultCompiler) {
// user using custom compiler, this means we cannot reuse the AST from
// the descriptor as they might be different.
inAST = undefined
}

if (inAST?.codegenNode) {
// input AST has codegenNode - it has already been transformed and cannot
// be reused. We need to parse a fresh one.
// be reused. We need to parse a fresh one. Can't just use `source` here
// since we need the AST location info to be relative to the entire SFC.
const newAST = compiler.parse(inAST.source, {
parseMode: 'sfc',
onError: e => errors.push(e)
Expand Down Expand Up @@ -241,7 +251,7 @@ function doCompileTemplate({
// inMap should be the map produced by ./parse.ts which is a simple line-only
// mapping. If it is present, we need to adjust the final map and errors to
// reflect the original line numbers.
if (inMap) {
if (inMap && !inAST) {
if (map) {
map = mapLines(inMap, map)
}
Expand Down
5 changes: 1 addition & 4 deletions packages/compiler-sfc/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,7 @@ export function parse(
)
}
}
// only genMap for template when it needs preprocessor
if (descriptor.template && descriptor.template.lang) {
genMap(descriptor.template)
}
genMap(descriptor.template)
genMap(descriptor.script)
descriptor.styles.forEach(genMap)
descriptor.customBlocks.forEach(genMap)
Expand Down

0 comments on commit 79d3cc6

Please sign in to comment.