]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: parser support for script setup
authorEvan You <yyx990803@gmail.com>
Fri, 3 Jul 2020 19:08:41 +0000 (15:08 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 9 Jul 2020 16:17:28 +0000 (12:17 -0400)
packages/compiler-sfc/__tests__/parse.spec.ts
packages/compiler-sfc/src/parse.ts

index d7d8ca6b2e817f429cc8fbb3e9850b5a21ae99d1..1378e64a56e6b7202cebc15706ebbbfb2bf1272b 100644 (file)
@@ -146,15 +146,33 @@ h1 { color: red }
     test('should only allow single template element', () => {
       parse(`<template><div/></template><template><div/></template>`)
       expect(
-        `Single file component can contain only one template element`
+        `Single file component can contain only one <template> element`
       ).toHaveBeenWarned()
     })
 
     test('should only allow single script element', () => {
       parse(`<script>console.log(1)</script><script>console.log(1)</script>`)
       expect(
-        `Single file component can contain only one script element`
+        `Single file component can contain only one <script> element`
       ).toHaveBeenWarned()
     })
+
+    test('should only allow single script setup element', () => {
+      parse(
+        `<script setup>console.log(1)</script><script setup>console.log(1)</script>`
+      )
+      expect(
+        `Single file component can contain only one <script setup> element`
+      ).toHaveBeenWarned()
+    })
+
+    test('should not warn script & script setup', () => {
+      parse(
+        `<script setup>console.log(1)</script><script>console.log(1)</script>`
+      )
+      expect(
+        `Single file component can contain only one`
+      ).not.toHaveBeenWarned()
+    })
   })
 })
index 2e8bd719eb6a28335d4c1f19bb3f91e57fb359a8..6e92acaacb3714d3a074d6e4973528f75673dcf0 100644 (file)
@@ -35,6 +35,7 @@ export interface SFCTemplateBlock extends SFCBlock {
 
 export interface SFCScriptBlock extends SFCBlock {
   type: 'script'
+  setup?: boolean
 }
 
 export interface SFCStyleBlock extends SFCBlock {
@@ -47,6 +48,7 @@ export interface SFCDescriptor {
   filename: string
   template: SFCTemplateBlock | null
   script: SFCScriptBlock | null
+  scriptSetup: SFCScriptBlock | null
   styles: SFCStyleBlock[]
   customBlocks: SFCBlock[]
 }
@@ -86,6 +88,7 @@ export function parse(
     filename,
     template: null,
     script: null,
+    scriptSetup: null,
     styles: [],
     customBlocks: []
   }
@@ -140,11 +143,16 @@ export function parse(
         }
         break
       case 'script':
-        if (!descriptor.script) {
-          descriptor.script = createBlock(node, source, pad) as SFCScriptBlock
-        } else {
-          warnDuplicateBlock(source, filename, node)
+        const block = createBlock(node, source, pad) as SFCScriptBlock
+        if (block.setup && !descriptor.scriptSetup) {
+          descriptor.scriptSetup = block
+          break
         }
+        if (!block.setup && !descriptor.script) {
+          descriptor.script = block
+          break
+        }
+        warnDuplicateBlock(source, filename, node, block.setup)
         break
       case 'style':
         descriptor.styles.push(createBlock(node, source, pad) as SFCStyleBlock)
@@ -183,7 +191,8 @@ export function parse(
 function warnDuplicateBlock(
   source: string,
   filename: string,
-  node: ElementNode
+  node: ElementNode,
+  isScriptSetup = false
 ) {
   const codeFrame = generateCodeFrame(
     source,
@@ -192,9 +201,9 @@ function warnDuplicateBlock(
   )
   const location = `${filename}:${node.loc.start.line}:${node.loc.start.column}`
   console.warn(
-    `Single file component can contain only one ${
-      node.tag
-    } element (${location}):\n\n${codeFrame}`
+    `Single file component can contain only one <${node.tag}${
+      isScriptSetup ? ` setup` : ``
+    }> element (${location}):\n\n${codeFrame}`
   )
 }
 
@@ -241,6 +250,8 @@ function createBlock(
         }
       } else if (type === 'template' && p.name === 'functional') {
         ;(block as SFCTemplateBlock).functional = true
+      } else if (type === 'script' && p.name === 'setup') {
+        ;(block as SFCScriptBlock).setup = true
       }
     }
   })