]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): removeSpecifier issue when removing initial imports (script-setup...
authorMatias Capeletto <matias.capeletto@gmail.com>
Sat, 13 Feb 2021 09:06:34 +0000 (10:06 +0100)
committerGitHub <noreply@github.com>
Sat, 13 Feb 2021 09:06:34 +0000 (10:06 +0100)
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
packages/compiler-sfc/__tests__/compileScript.spec.ts
packages/compiler-sfc/src/compileScript.ts

index 01e2b80981cf4028a57eadc442c464558f4319ac..59ef9b1b7ee89173062e947b531d6fdeb4bc5a1e 100644 (file)
@@ -164,6 +164,25 @@ return { x }
 }"
 `;
 
+exports[`SFC compile <script setup> imports should allow defineProps/Emit at the start of imports 1`] = `
+"import { ref } from 'vue'
+      
+export default {
+  expose: [],
+  props: ['foo'],
+  emits: ['bar'],
+  setup(__props) {
+
+      
+      
+      const r = ref(0)
+      
+return { r, ref }
+}
+
+}"
+`;
+
 exports[`SFC compile <script setup> imports should extract comment for import or type declarations 1`] = `
 "import a from 'a' // comment
         import b from 'b'
index 218614795f131a5e5825fc08ed07b1c3d820b788..0594bf26dbfacdd65b219bbceaef62d7f5b46d6e 100644 (file)
@@ -141,6 +141,18 @@ const myEmit = defineEmit(['foo', 'bar'])
       )
     })
 
+    // #2740
+    test('should allow defineProps/Emit at the start of imports', () => {
+      assertCode(
+        compile(`<script setup>
+      import { defineProps, defineEmit, ref } from 'vue'
+      defineProps(['foo'])
+      defineEmit(['bar'])
+      const r = ref(0)
+      </script>`).content
+      )
+    })
+
     test('dedupe between user & helper', () => {
       const { content } = compile(`
       <script setup>
index 7b2a869c758bc32a0b2f59d04540a9a9a76913b8..0d58ce8e7b903c3ba445c9e91e312561439a779e 100644 (file)
@@ -597,19 +597,23 @@ export function compileScript(
 
       // dedupe imports
       let removed = 0
-      let prev: Node | undefined, next: Node | undefined
-      const removeSpecifier = (node: Node) => {
+      const removeSpecifier = (i: number) => {
+        const removeLeft = i > removed
         removed++
+        const current = node.specifiers[i]
+        const next = node.specifiers[i + 1]
         s.remove(
-          prev ? prev.end! + startOffset : node.start! + startOffset,
-          next && !prev ? next.start! + startOffset : node.end! + startOffset
+          removeLeft
+            ? node.specifiers[i - 1].end! + startOffset
+            : current.start! + startOffset,
+          next && !removeLeft
+            ? next.start! + startOffset
+            : current.end! + startOffset
         )
       }
 
       for (let i = 0; i < node.specifiers.length; i++) {
         const specifier = node.specifiers[i]
-        prev = node.specifiers[i - 1]
-        next = node.specifiers[i + 1]
         const local = specifier.local.name
         const imported =
           specifier.type === 'ImportSpecifier' &&
@@ -621,11 +625,11 @@ export function compileScript(
           source === 'vue' &&
           (imported === DEFINE_PROPS || imported === DEFINE_EMIT)
         ) {
-          removeSpecifier(specifier)
+          removeSpecifier(i)
         } else if (existing) {
           if (existing.source === source && existing.imported === imported) {
             // already imported in <script setup>, dedupe
-            removeSpecifier(specifier)
+            removeSpecifier(i)
           } else {
             error(`different imports aliased to same local name.`, specifier)
           }