Przeglądaj źródła

fix(compiler-sfc): fix rewriteDefault edge cases

close #13060
close #12892
close #12906
Evan You 2 lat temu
rodzic
commit
25f97a5033

+ 1 - 1
packages/compiler-sfc/src/compileScript.ts

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

+ 8 - 2
packages/compiler-sfc/src/rewriteDefault.ts

@@ -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} = `)

+ 70 - 4
packages/compiler-sfc/test/rewriteDefault.spec.ts

@@ -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"
+    `)
+  })
 })