Skip to content

Commit

Permalink
fix(compiler-sfc): fix binding type for constants when hoistStatic is…
Browse files Browse the repository at this point in the history
… disabled (vuejs#8029)
  • Loading branch information
sxzz authored and IAmSSH committed Apr 29, 2023
1 parent 4f01574 commit 3b7e28d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,15 @@ return () => {}
}"
`;
exports[`sfc hoist static > should not hoist when disabled 1`] = `
"export default {
setup(__props) {
const foo = 'bar'
return () => {}
}
}"
`;
2 changes: 1 addition & 1 deletion packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('SFC compile <script setup>', () => {
expect(bindings).toStrictEqual({
x: BindingTypes.SETUP_MAYBE_REF,
a: BindingTypes.SETUP_LET,
b: BindingTypes.LITERAL_CONST,
b: BindingTypes.SETUP_CONST,
c: BindingTypes.SETUP_CONST,
d: BindingTypes.SETUP_CONST,
xx: BindingTypes.SETUP_MAYBE_REF,
Expand Down
17 changes: 16 additions & 1 deletion packages/compiler-sfc/__tests__/compileScriptHoistStatic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,22 @@ describe('sfc hoist static', () => {
</script>
`)
expect(bindings).toStrictEqual({
foo: BindingTypes.LITERAL_CONST
foo: BindingTypes.SETUP_CONST
})
assertCode(content)
})

test('should not hoist when disabled', () => {
const { content, bindings } = compile(
`
<script setup>
const foo = 'bar'
</script>
`,
{ hoistStatic: false }
)
expect(bindings).toStrictEqual({
foo: BindingTypes.SETUP_CONST
})
assertCode(content)
})
Expand Down
35 changes: 29 additions & 6 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ export function compileScript(
if (!node) return
walkIdentifiers(node, id => {
const binding = setupBindings[id.name]
if (binding && (binding !== BindingTypes.LITERAL_CONST || !hoistStatic)) {
if (binding && binding !== BindingTypes.LITERAL_CONST) {
error(
`\`${method}()\` in <script setup> cannot reference locally ` +
`declared variables because it will be hoisted outside of the ` +
Expand Down Expand Up @@ -1258,7 +1258,13 @@ export function compileScript(
}
}
if (node.declaration) {
walkDeclaration(node.declaration, scriptBindings, vueImportAliases)
walkDeclaration(
'script',
node.declaration,
scriptBindings,
vueImportAliases,
hoistStatic
)
}
} else if (
(node.type === 'VariableDeclaration' ||
Expand All @@ -1267,7 +1273,13 @@ export function compileScript(
node.type === 'TSEnumDeclaration') &&
!node.declare
) {
walkDeclaration(node, scriptBindings, vueImportAliases)
walkDeclaration(
'script',
node,
scriptBindings,
vueImportAliases,
hoistStatic
)
}
}

Expand Down Expand Up @@ -1394,7 +1406,13 @@ export function compileScript(
node.type === 'TSEnumDeclaration') &&
!node.declare
) {
isAllLiteral = walkDeclaration(node, setupBindings, vueImportAliases)
isAllLiteral = walkDeclaration(
'scriptSetup',
node,
setupBindings,
vueImportAliases,
hoistStatic
)
}

// hoist literal constants
Expand Down Expand Up @@ -1891,9 +1909,11 @@ function registerBinding(
}

function walkDeclaration(
from: 'script' | 'scriptSetup',
node: Declaration,
bindings: Record<string, BindingTypes>,
userImportAliases: Record<string, string>
userImportAliases: Record<string, string>,
hoistStatic: boolean
): boolean {
let isAllLiteral = false

Expand All @@ -1918,7 +1938,10 @@ function walkDeclaration(
if (id.type === 'Identifier') {
let bindingType
const userReactiveBinding = userImportAliases['reactive']
if (isAllLiteral || (isConst && isStaticNode(init!))) {
if (
(hoistStatic || from === 'script') &&
(isAllLiteral || (isConst && isStaticNode(init!)))
) {
bindingType = BindingTypes.LITERAL_CONST
} else if (isCallOf(init, userReactiveBinding)) {
// treat reactive() calls as let since it's meant to be mutable
Expand Down

0 comments on commit 3b7e28d

Please sign in to comment.