fix(compiler-sfc): fix rewriteDefault edge cases

close #13060
close #12892
close #12906
This commit is contained in:
Evan You 2023-12-06 17:25:12 +08:00
parent 10c2a87c70
commit 25f97a5033
3 changed files with 79 additions and 7 deletions

View File

@ -1575,7 +1575,7 @@ function extractRuntimeEmits(
}
function extractEventNames(
eventName: Identifier | RestElement,
eventName: ArrayPattern | Identifier | ObjectPattern | RestElement,
emits: Set<string>
) {
if (

View File

@ -42,8 +42,14 @@ export function rewriteDefault(
}).program.body
ast.forEach(node => {
if (node.type === 'ExportDefaultDeclaration') {
if (node.declaration.type === 'ClassDeclaration') {
s.overwrite(node.start!, node.declaration.id.start!, `class `)
if (node.declaration.type === 'ClassDeclaration' && node.declaration.id) {
let start: number =
node.declaration.decorators && node.declaration.decorators.length > 0
? node.declaration.decorators[
node.declaration.decorators.length - 1
].end!
: node.start!
s.overwrite(start, node.declaration.id.start!, ` class `)
s.append(`\nconst ${as} = ${node.declaration.id.name}`)
} else {
s.overwrite(node.start!, node.declaration.start!, `const ${as} = `)

View File

@ -190,7 +190,7 @@ describe('compiler sfc: rewriteDefault', () => {
).toMatchInlineSnapshot(`
"/*
export default class Foo {}*/
class Bar {}
class Bar {}
const script = Bar"
`)
})
@ -206,7 +206,10 @@ describe('compiler sfc: rewriteDefault', () => {
test('@Component\nexport default class w/ comments', async () => {
expect(
rewriteDefault(`// export default\n@Component\nexport default class Foo {}`, 'script')
rewriteDefault(
`// export default\n@Component\nexport default class Foo {}`,
'script'
)
).toMatchInlineSnapshot(`
"// export default
@Component
@ -231,15 +234,78 @@ describe('compiler sfc: rewriteDefault', () => {
test('@Component\nexport default class w/ comments 3', async () => {
expect(
rewriteDefault(
`/*\n@Component\nexport default class Foo {}*/\n` + `export default class Bar {}`,
`/*\n@Component\nexport default class Foo {}*/\n` +
`export default class Bar {}`,
'script'
)
).toMatchInlineSnapshot(`
"/*
@Component
export default class Foo {}*/
class Bar {}
class Bar {}
const script = Bar"
`)
})
// #13060
test('@Component\nexport default class w/ comments 4', async () => {
expect(
rewriteDefault(
`@Component
export default class App extends Vue {
/* default <- This word means my component is not built correctly */
@Prop({ type: String, required: true })
protected someString: string;
}`,
'script'
)
).toMatchInlineSnapshot(`
"@Component
class App extends Vue {
/* default <- This word means my component is not built correctly */
@Prop({ type: String, required: true })
protected someString: string;
}
const script = App"
`)
})
// #12892
test('@Component\nexport default class w/ comments 5', async () => {
expect(
rewriteDefault(
`@Component({})
export default class HelloWorld extends Vue {
test = "";
mounted() {
console.log("mounted!");
this.test = "Hallo Welt!";
}
exportieren(): void {
// do nothing
}
defaultWert(): void {
// do nothing
}
}`,
'script',
['typescript', 'decorators-legacy']
)
).toMatchInlineSnapshot(`
"@Component({}) class HelloWorld extends Vue {
test = "";
mounted() {
console.log("mounted!");
this.test = "Hallo Welt!";
}
exportieren(): void {
// do nothing
}
defaultWert(): void {
// do nothing
}
}
const script = HelloWorld"
`)
})
})