]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-sfc): warn duplicate block (#451)
authorlikui <2218301630@qq.com>
Thu, 14 Nov 2019 16:50:13 +0000 (00:50 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 14 Nov 2019 16:50:13 +0000 (11:50 -0500)
packages/compiler-sfc/__tests__/parse.spec.ts [new file with mode: 0644]
packages/compiler-sfc/src/parse.ts

diff --git a/packages/compiler-sfc/__tests__/parse.spec.ts b/packages/compiler-sfc/__tests__/parse.spec.ts
new file mode 100644 (file)
index 0000000..14cb9dc
--- /dev/null
@@ -0,0 +1,21 @@
+import { parse } from '../src'
+import { mockWarn } from '@vue/runtime-test'
+
+describe('compiler:sfc', () => {
+  mockWarn()
+  describe('error', () => {
+    test('should only allow single template element', () => {
+      parse(`<template><div/></template><template><div/></template>`)
+      expect(
+        `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`
+      ).toHaveBeenWarned()
+    })
+  })
+})
index 9cfded626a02d3b1649896f176a3a76c23b99d5f..de8945ddaa1411075bf785784f1197b6143de8a0 100644 (file)
@@ -7,6 +7,7 @@ import {
   SourceLocation
 } from '@vue/compiler-core'
 import { RawSourceMap } from 'source-map'
+import { generateCodeFrame } from '@vue/shared'
 
 export interface SFCParseOptions {
   needMap?: boolean
@@ -78,14 +79,14 @@ export function parse(
         if (!sfc.template) {
           sfc.template = createBlock(node) as SFCTemplateBlock
         } else {
-          // TODO warn duplicate template
+          warnDuplicateBlock(source, filename, node)
         }
         break
       case 'script':
         if (!sfc.script) {
           sfc.script = createBlock(node) as SFCScriptBlock
         } else {
-          // TODO warn duplicate script
+          warnDuplicateBlock(source, filename, node)
         }
         break
       case 'style':
@@ -105,6 +106,24 @@ export function parse(
   return sfc
 }
 
+function warnDuplicateBlock(
+  source: string,
+  filename: string,
+  node: ElementNode
+) {
+  const codeFrame = generateCodeFrame(
+    source,
+    node.loc.start.offset,
+    node.loc.end.offset
+  )
+  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}`
+  )
+}
+
 function createBlock(node: ElementNode): SFCBlock {
   const type = node.tag
   const text = node.children[0] as TextNode