feat(compiler-sfc): warn duplicate block (#451)
This commit is contained in:
parent
8688acc36f
commit
7f6abda6dd
21
packages/compiler-sfc/__tests__/parse.spec.ts
Normal file
21
packages/compiler-sfc/__tests__/parse.spec.ts
Normal file
@ -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()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -7,6 +7,7 @@ import {
|
|||||||
SourceLocation
|
SourceLocation
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
import { RawSourceMap } from 'source-map'
|
import { RawSourceMap } from 'source-map'
|
||||||
|
import { generateCodeFrame } from '@vue/shared'
|
||||||
|
|
||||||
export interface SFCParseOptions {
|
export interface SFCParseOptions {
|
||||||
needMap?: boolean
|
needMap?: boolean
|
||||||
@ -78,14 +79,14 @@ export function parse(
|
|||||||
if (!sfc.template) {
|
if (!sfc.template) {
|
||||||
sfc.template = createBlock(node) as SFCTemplateBlock
|
sfc.template = createBlock(node) as SFCTemplateBlock
|
||||||
} else {
|
} else {
|
||||||
// TODO warn duplicate template
|
warnDuplicateBlock(source, filename, node)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'script':
|
case 'script':
|
||||||
if (!sfc.script) {
|
if (!sfc.script) {
|
||||||
sfc.script = createBlock(node) as SFCScriptBlock
|
sfc.script = createBlock(node) as SFCScriptBlock
|
||||||
} else {
|
} else {
|
||||||
// TODO warn duplicate script
|
warnDuplicateBlock(source, filename, node)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'style':
|
case 'style':
|
||||||
@ -105,6 +106,24 @@ export function parse(
|
|||||||
return sfc
|
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 {
|
function createBlock(node: ElementNode): SFCBlock {
|
||||||
const type = node.tag
|
const type = node.tag
|
||||||
const text = node.children[0] as TextNode
|
const text = node.children[0] as TextNode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user