From 87b48f9103f467c3ad33b039ccf845aed9a281d7 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Mon, 10 Oct 2022 03:44:27 +0800 Subject: [PATCH] fix(ssr): track var as function scope (#10388) --- .../node/ssr/__tests__/ssrTransform.spec.ts | 24 +++++++++++++++++++ packages/vite/src/node/ssr/ssrTransform.ts | 24 ++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index a5ca20c9be3d09..33d5071a054a99 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -787,3 +787,27 @@ export class Test { Object.defineProperty(__vite_ssr_exports__, \\"Test\\", { enumerable: true, configurable: true, get(){ return Test }});;" `) }) + +// #10386 +test('track var scope by function', async () => { + expect( + await ssrTransformSimpleCode(` +import { foo, bar } from 'foobar' +function test() { + if (true) { + var foo = () => { var why = 'would' }, bar = 'someone' + } + return [foo, bar] +}`) + ).toMatchInlineSnapshot(` + " + const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foobar\\"); + + function test() { + if (true) { + var foo = () => { var why = 'would' }, bar = 'someone' + } + return [foo, bar] + }" + `) +}) diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index 12c3bb354b6c9e..eefdf29f70d7a1 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -5,6 +5,7 @@ import type { Identifier, Pattern, Property, + VariableDeclaration, Node as _Node } from 'estree' import { extract_names as extractNames } from 'periscopic' @@ -316,6 +317,7 @@ function walk( { onIdentifier, onImportMeta, onDynamicImport }: Visitors ) { const parentStack: Node[] = [] + const varKindStack: VariableDeclaration['kind'][] = [] const scopeMap = new WeakMap<_Node, Set>() const identifiers: [id: any, stack: Node[]][] = [] @@ -375,6 +377,11 @@ function walk( parentStack.unshift(parent) } + // track variable declaration kind stack used by VariableDeclarator + if (node.type === 'VariableDeclaration') { + varKindStack.unshift(node.kind) + } + if (node.type === 'MetaProperty' && node.meta.name === 'import') { onImportMeta(node) } else if (node.type === 'ImportExpression') { @@ -434,7 +441,10 @@ function walk( // mark property in destructuring pattern setIsNodeInPattern(node) } else if (node.type === 'VariableDeclarator') { - const parentFunction = findParentScope(parentStack) + const parentFunction = findParentScope( + parentStack, + varKindStack[0] === 'var' + ) if (parentFunction) { handlePattern(node.id, parentFunction) } @@ -449,6 +459,10 @@ function walk( ) { parentStack.shift() } + + if (node.type === 'VariableDeclaration') { + varKindStack.shift() + } } }) @@ -538,8 +552,12 @@ function isFunction(node: _Node): node is FunctionNode { const scopeNodeTypeRE = /(?:Function|Class)(?:Expression|Declaration)$|Method$|^IfStatement$/ -function findParentScope(parentStack: _Node[]): _Node | undefined { - return parentStack.find((i) => scopeNodeTypeRE.test(i.type)) +function findParentScope( + parentStack: _Node[], + isVar = false +): _Node | undefined { + const regex = isVar ? functionNodeTypeRE : scopeNodeTypeRE + return parentStack.find((i) => regex.test(i.type)) } function isInDestructuringAssignment(