-
- Notifications
You must be signed in to change notification settings - Fork 8.9k
Description
Version
3.0.2
Reproduction link
https://codesandbox.io/s/autumn-wildflower-cqpew?file=/src/index.ts
Steps to reproduce
import { parse } from "@vue/compiler-sfc"; import { parse as parse2 } from "@vue/component-compiler-utils"; const source = `\ <template></template> <script></script> <style></style> `; const vue3 = parse(source); console.log("vue3", vue3.descriptor); // template: null // script: null // style: [] const vue2 = parse2({ source, compiler: require("vue-template-compiler") }); console.log("vue2", vue2); // template: { ... } // script: { ... } // style: [{ ... }]
What is expected?
Consistent with vue2, get the descriptor of empty block.
What is actually happening?
The descriptor of empty block is null
.
Related issues
Explanation
It seems to be intended as the tests show:
However, it may cause some breakings in SFC:
- An empty
<template>
block means it should render empty string, which is different from no<template>
block. - If
@vue/compiler-sfc
returnnull
for empty<template>
, it's difficult forvue-loader
/rollup-plugin-vue
to determine if the SFC has<template>
block or not.
In fact, the only difference is a runtime warning during development:
IMO:
- An empty
<template>
block is intended by user, which should not be warned. - No
<template>
block might be a fault, which should be warned.
Questions / Discussion
As we do not have a full specification for vue SFC, some edge cases are not so specific, and the behavior of vue-loader
/ rollup-plugin-vue
/ other implementations can be inconsistent.
Here are some edge cases that might need to be determined:
Case A: SFC has both <template>
and script.render
:
<template> <div></div> </template> <script> export default { render() {} } </script>
Which is expected?
- replace
script.render
with<template>
- use
script.render
Current behavior of
vue-loader
androllup-plugin-vue
is the first one.
Case B: SFC has empty <template>
and script.render
:
<template></template> <script> export default { render() {} } </script>
Which is expected?
- replace
script.render
with empty<template>
- use
script.render
This is affected by this issue.
Case C: SFC has empty <template>
, but does not have script.render
:
<template></template> <script> export default { // no render() } </script>
Which is expected?
- replace
script.render
with empty<template>
- replace
script.render
with a NOOP as default render - keep it
undefined
(will print a runtime warning)
This is affected by this issue.
Case D: SFC does not have <template>
nor script.render
:
<script> export default { // no render() } </script>
Which is expected?
- replace
script.render
with a NOOP as default render - keep it
undefined
(will print a runtime warning)