UNPKG

@vuedx/compiler-sfc

Version:

This package extracts `parse()` function [@vue/compiler-sfc] as ES module.

1 lines 11.2 kB
{"version":3,"file":"index.cjs","sources":["../src/parse.ts"],"sourcesContent":["import type { ElementNode } from '@vue/compiler-core'\nimport { parse as fallback } from '@vue/compiler-dom'\nimport type {\n CompilerError,\n SFCBlock,\n SFCParseOptions,\n SFCScriptBlock,\n SFCStyleBlock,\n SFCTemplateBlock,\n} from '@vue/compiler-sfc'\nimport { first, last } from '@vuedx/shared'\nimport { NodeTypes } from '@vuedx/template-ast-types'\n\nexport interface SFCParseResult {\n descriptor: SFCDescriptor\n errors: Array<CompilerError | SyntaxError>\n}\n\nexport interface SFCDescriptor {\n script: SFCScriptBlock | null\n scriptSetup: SFCScriptBlock | null\n template: SFCTemplateBlock | null\n styles: SFCStyleBlock[]\n customBlocks: SFCBlock[]\n}\n\nexport type Parser = Pick<Required<SFCParseOptions>['compiler'], 'parse'>\n\nlet isParsingBrokenTemplate = false\n\nexport function parse(\n source: string,\n compiler: Parser = {\n parse: fallback,\n },\n): SFCParseResult {\n const descriptor: SFCDescriptor = {\n script: null,\n scriptSetup: null,\n template: null,\n styles: [],\n customBlocks: [],\n }\n const errors: Array<CompilerError | SyntaxError> = []\n const ast = compiler.parse(source, {\n // there are no components at SFC parsing level\n isNativeTag: () => true,\n decodeEntities: (string) => string,\n // preserve all whitespace\n isPreTag: () => true,\n getTextMode: ({ tag, props }, parent) => {\n // all top level elements except <template> are parsed as raw text\n // containers\n if (\n (parent == null && tag !== 'template') ||\n // <template lang=\"xxx\"> should also be treated as raw text\n (tag === 'template' &&\n props.some(\n (p) =>\n p.type === NodeTypes.ATTRIBUTE &&\n p.name === 'lang' &&\n p.value != null &&\n p.value.content.length > 0 &&\n p.value.content !== 'html',\n ))\n ) {\n return 2 /* RAWTEXT */\n } else {\n return 0 /* DATA */\n }\n },\n onError: (e) => {\n errors.push(e)\n },\n })\n\n ast.children.forEach((node) => {\n if (node.type !== 1 /* ELEMENT */) {\n return\n }\n\n switch (node.tag) {\n case 'template':\n if (descriptor.template == null) {\n descriptor.template = createBlock(node, source) as SFCTemplateBlock\n } else {\n errors.push(createDuplicateBlockError(node))\n }\n break\n case 'script':\n {\n const scriptBlock = createBlock(node, source) as SFCScriptBlock\n const isSetup = scriptBlock.attrs['setup'] != null\n if (isSetup) {\n if (descriptor.scriptSetup == null) {\n descriptor.scriptSetup = scriptBlock\n } else {\n errors.push(createDuplicateBlockError(node, isSetup))\n }\n } else {\n if (descriptor.script == null) {\n descriptor.script = scriptBlock\n } else {\n errors.push(createDuplicateBlockError(node, isSetup))\n }\n }\n }\n break\n case 'style':\n {\n const styleBlock = createBlock(node, source) as SFCStyleBlock\n descriptor.styles.push(styleBlock)\n }\n break\n default:\n descriptor.customBlocks.push(createBlock(node, source))\n break\n }\n })\n\n if (descriptor.template != null && !isParsingBrokenTemplate) {\n const start = descriptor.template.loc.start.offset\n const end = source.lastIndexOf('</template')\n if (end < descriptor.template.loc.end.offset) {\n // There is an parsing error in the template.\n const proxy =\n source.slice(0, start) +\n placeholder(source.slice(start, end)) +\n source.slice(end)\n\n isParsingBrokenTemplate = true\n try {\n const result = parse(proxy, compiler)\n\n if (result.descriptor.template != null) {\n result.descriptor.template.content = source.slice(start, end)\n result.descriptor.template.loc.source = source.slice(start, end)\n }\n\n return result\n } finally {\n isParsingBrokenTemplate = false\n }\n }\n }\n\n if (descriptor.scriptSetup != null) {\n if (descriptor.scriptSetup.src != null) {\n errors.push(\n new SyntaxError(\n `<script setup> cannot use the \"src\" attribute because ` +\n `its syntax will be ambiguous outside of the component.`,\n ),\n )\n descriptor.scriptSetup = null\n }\n if (descriptor.script?.src != null) {\n errors.push(\n new SyntaxError(\n `<script> cannot use the \"src\" attribute when <script setup> is ` +\n `also present because they must be processed together.`,\n ),\n )\n descriptor.script = null\n }\n }\n\n return { descriptor, errors }\n}\nfunction createDuplicateBlockError(\n node: ElementNode,\n isScriptSetup = false,\n): CompilerError {\n const err = new SyntaxError(\n `Single file component can contain only one <${node.tag}${\n isScriptSetup ? ` setup` : ``\n }> element`,\n ) as CompilerError\n err.loc = node.loc\n return err\n}\nfunction createBlock(node: ElementNode, source: string): SFCBlock {\n const type = node.tag\n let { start, end } = node.loc\n let content = ''\n if (node.children.length > 0) {\n start = first(node.children).loc.start\n end = last(node.children).loc.end\n content = source.slice(start.offset, end.offset)\n } else {\n const offset = node.loc.source.indexOf(`</`)\n if (offset > -1) {\n start = {\n line: start.line,\n column: start.column + offset,\n offset: start.offset + offset,\n }\n }\n end = { ...start }\n }\n const loc = {\n source: content,\n start,\n end,\n }\n const attrs: Record<string, string | true> = {}\n const block: SFCBlock = {\n type,\n content,\n loc,\n attrs,\n }\n node.props.forEach((p) => {\n if (p.type === NodeTypes.ATTRIBUTE) {\n attrs[p.name] =\n p.value != null && p.value.content.trim() !== ''\n ? p.value.content\n : true\n\n if (p.name === 'lang') {\n if (p.value != null) block.lang = p.value.content\n } else if (p.name === 'src') {\n if (p.value != null) block.src = p.value.content\n } else if (type === 'style') {\n if (p.name === 'scoped') {\n ;(block as SFCStyleBlock).scoped = true\n } else if (p.name === 'module') {\n ;(block as SFCStyleBlock).module = attrs[p.name]\n }\n } else if (type === 'script' && p.name === 'setup') {\n ;(block as SFCScriptBlock).setup = attrs['setup']\n }\n }\n })\n return block\n}\n\nfunction placeholder(content: string): string {\n let output = ''\n const nl = '\\n'.charCodeAt(0)\n for (let i = 0; i < content.length; i++) {\n output += content.charCodeAt(i) === nl ? '\\n' : ' '\n }\n return output\n}\n"],"names":["fallback","NodeTypes"],"mappings":"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"}