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,
</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)
})
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 ` +
}
}
if (node.declaration) {
- walkDeclaration(node.declaration, scriptBindings, vueImportAliases)
+ walkDeclaration(
+ 'script',
+ node.declaration,
+ scriptBindings,
+ vueImportAliases,
+ hoistStatic
+ )
}
} else if (
(node.type === 'VariableDeclaration' ||
node.type === 'TSEnumDeclaration') &&
!node.declare
) {
- walkDeclaration(node, scriptBindings, vueImportAliases)
+ walkDeclaration(
+ 'script',
+ node,
+ scriptBindings,
+ vueImportAliases,
+ hoistStatic
+ )
}
}
node.type === 'TSEnumDeclaration') &&
!node.declare
) {
- isAllLiteral = walkDeclaration(node, setupBindings, vueImportAliases)
+ isAllLiteral = walkDeclaration(
+ 'scriptSetup',
+ node,
+ setupBindings,
+ vueImportAliases,
+ hoistStatic
+ )
}
// hoist literal constants
}
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
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