Skip to content

Commit

Permalink
fix(compiler-sfc): ensure consistent behavior of export default rende…
Browse files Browse the repository at this point in the history
…r with script setup

close vuejs#4980
  • Loading branch information
yyx990803 authored and iwusong committed May 13, 2022
1 parent e434d1c commit 1b213c6
Showing 1 changed file with 40 additions and 21 deletions.
61 changes: 40 additions & 21 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ export function compileScript(
let hasDefineEmitCall = false
let hasDefineExposeCall = false
let hasDefaultExportName = false
let hasDefaultExportRender = false
let propsRuntimeDecl: Node | undefined
let propsRuntimeDefaults: ObjectExpression | undefined
let propsDestructureDecl: Node | undefined
Expand Down Expand Up @@ -819,8 +820,11 @@ export function compileScript(
// export default
defaultExport = node

// check if user has manually specified `name` option in export default
// if yes, skip infer later
// check if user has manually specified `name` or 'render` option in
// export default
// if has name, skip name inference
// if has render and no template, generate return object instead of
// empty render function (#4980)
let optionProperties
if (defaultExport.declaration.type === 'ObjectExpression') {
optionProperties = defaultExport.declaration.properties
Expand All @@ -830,12 +834,25 @@ export function compileScript(
) {
optionProperties = defaultExport.declaration.arguments[0].properties
}
hasDefaultExportName = !!optionProperties?.some(
s =>
s.type === 'ObjectProperty' &&
s.key.type === 'Identifier' &&
s.key.name === 'name'
)
if (optionProperties) {
for (const s of optionProperties) {
if (
s.type === 'ObjectProperty' &&
s.key.type === 'Identifier' &&
s.key.name === 'name'
) {
hasDefaultExportName = true
}
if (
(s.type === 'ObjectMethod' || s.type === 'ObjectProperty') &&
s.key.type === 'Identifier' &&
s.key.name === 'render'
) {
// TODO warn when we provide a better way to do it?
hasDefaultExportRender = true
}
}
}

// export default { ... } --> const __default__ = { ... }
const start = node.start! + scriptStartOffset!
Expand Down Expand Up @@ -1303,7 +1320,21 @@ export function compileScript(

// 10. generate return statement
let returned
if (options.inlineTemplate) {
if (!options.inlineTemplate || (!sfc.template && hasDefaultExportRender)) {
// non-inline mode, or has manual render in normal <script>
// return bindings from script and script setup
const allBindings: Record<string, any> = {
...scriptBindings,
...setupBindings
}
for (const key in userImports) {
if (!userImports[key].isType && userImports[key].isUsedInTemplate) {
allBindings[key] = true
}
}
returned = `{ ${Object.keys(allBindings).join(', ')} }`
} else {
// inline mode
if (sfc.template && !sfc.template.src) {
if (options.templateOptions && options.templateOptions.ssr) {
hasInlinedSsrRenderFn = true
Expand Down Expand Up @@ -1361,18 +1392,6 @@ export function compileScript(
} else {
returned = `() => {}`
}
} else {
// return bindings from script and script setup
const allBindings: Record<string, any> = {
...scriptBindings,
...setupBindings
}
for (const key in userImports) {
if (!userImports[key].isType && userImports[key].isUsedInTemplate) {
allBindings[key] = true
}
}
returned = `{ ${Object.keys(allBindings).join(', ')} }`
}

if (!options.inlineTemplate && !__TEST__) {
Expand Down

0 comments on commit 1b213c6

Please sign in to comment.