Skip to content

Commit 9060bf0

Browse files
authored
refactor(compiler-core): make ast.helpers a Set (#6774)
1 parent 7443174 commit 9060bf0

File tree

8 files changed

+112
-107
lines changed

8 files changed

+112
-107
lines changed

packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap

Lines changed: 81 additions & 81 deletions
Large diffs are not rendered by default.

packages/compiler-core/__tests__/codegen.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
4141
return {
4242
type: NodeTypes.ROOT,
4343
children: [],
44-
helpers: [],
44+
helpers: new Set(),
4545
components: [],
4646
directives: [],
4747
imports: [],
@@ -57,7 +57,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
5757
describe('compiler: codegen', () => {
5858
test('module mode preamble', () => {
5959
const root = createRoot({
60-
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
60+
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
6161
})
6262
const { code } = generate(root, { mode: 'module' })
6363
expect(code).toMatch(
@@ -68,7 +68,7 @@ describe('compiler: codegen', () => {
6868

6969
test('module mode preamble w/ optimizeImports: true', () => {
7070
const root = createRoot({
71-
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
71+
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
7272
})
7373
const { code } = generate(root, { mode: 'module', optimizeImports: true })
7474
expect(code).toMatch(
@@ -82,7 +82,7 @@ describe('compiler: codegen', () => {
8282

8383
test('function mode preamble', () => {
8484
const root = createRoot({
85-
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
85+
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
8686
})
8787
const { code } = generate(root, { mode: 'function' })
8888
expect(code).toMatch(`const _Vue = Vue`)
@@ -94,7 +94,7 @@ describe('compiler: codegen', () => {
9494

9595
test('function mode preamble w/ prefixIdentifiers: true', () => {
9696
const root = createRoot({
97-
helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
97+
helpers: new Set([CREATE_VNODE, RESOLVE_DIRECTIVE])
9898
})
9999
const { code } = generate(root, {
100100
mode: 'function',

packages/compiler-core/src/ast.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export type TemplateChildNode =
100100
export interface RootNode extends Node {
101101
type: NodeTypes.ROOT
102102
children: TemplateChildNode[]
103-
helpers: symbol[]
103+
helpers: Set<symbol>
104104
components: string[]
105105
directives: string[]
106106
hoists: (JSChildNode | null)[]
@@ -556,7 +556,7 @@ export function createRoot(
556556
return {
557557
type: NodeTypes.ROOT,
558558
children,
559-
helpers: [],
559+
helpers: new Set(),
560560
components: [],
561561
directives: [],
562562
hoists: [],

packages/compiler-core/src/codegen.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ export function generate(
208208
ssr
209209
} = context
210210

211-
const hasHelpers = ast.helpers.length > 0
211+
const helpers = Array.from(ast.helpers)
212+
const hasHelpers = helpers.length > 0
212213
const useWithBlock = !prefixIdentifiers && mode !== 'module'
213214
const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module'
214215
const isSetupInlined = !__BROWSER__ && !!options.inline
@@ -249,7 +250,7 @@ export function generate(
249250
// function mode const declarations should be inside with block
250251
// also they should be renamed to avoid collision with user properties
251252
if (hasHelpers) {
252-
push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`)
253+
push(`const { ${helpers.map(aliasHelper).join(', ')} } = _Vue`)
253254
push(`\n`)
254255
newline()
255256
}
@@ -330,11 +331,10 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
330331
// In prefix mode, we place the const declaration at top so it's done
331332
// only once; But if we not prefixing, we place the declaration inside the
332333
// with block so it doesn't incur the `in` check cost for every helper access.
333-
if (ast.helpers.length > 0) {
334+
const helpers = Array.from(ast.helpers)
335+
if (helpers.length > 0) {
334336
if (!__BROWSER__ && prefixIdentifiers) {
335-
push(
336-
`const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`
337-
)
337+
push(`const { ${helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`)
338338
} else {
339339
// "with" mode.
340340
// save Vue in a separate variable to avoid collision
@@ -350,7 +350,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
350350
CREATE_TEXT,
351351
CREATE_STATIC
352352
]
353-
.filter(helper => ast.helpers.includes(helper))
353+
.filter(helper => helpers.includes(helper))
354354
.map(aliasHelper)
355355
.join(', ')
356356
push(`const { ${staticHelpers} } = _Vue\n`)
@@ -386,30 +386,32 @@ function genModulePreamble(
386386
} = context
387387

388388
if (genScopeId && ast.hoists.length) {
389-
ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID)
389+
ast.helpers.add(PUSH_SCOPE_ID)
390+
ast.helpers.add(POP_SCOPE_ID)
390391
}
391392

392393
// generate import statements for helpers
393-
if (ast.helpers.length) {
394+
if (ast.helpers.size) {
395+
const helpers = Array.from(ast.helpers)
394396
if (optimizeImports) {
395397
// when bundled with webpack with code-split, calling an import binding
396398
// as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,
397399
// incurring both payload size increase and potential perf overhead.
398400
// therefore we assign the imports to variables (which is a constant ~50b
399401
// cost per-component instead of scaling with template size)
400402
push(
401-
`import { ${ast.helpers
403+
`import { ${helpers
402404
.map(s => helperNameMap[s])
403405
.join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
404406
)
405407
push(
406-
`\n// Binding optimization for webpack code-split\nconst ${ast.helpers
408+
`\n// Binding optimization for webpack code-split\nconst ${helpers
407409
.map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)
408410
.join(', ')}\n`
409411
)
410412
} else {
411413
push(
412-
`import { ${ast.helpers
414+
`import { ${helpers
413415
.map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
414416
.join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
415417
)

packages/compiler-core/src/transform.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ export function transform(root: RootNode, options: TransformOptions) {
324324
createRootCodegen(root, context)
325325
}
326326
// finalize meta information
327-
root.helpers = [...context.helpers.keys()]
327+
root.helpers = new Set([...context.helpers.keys()])
328328
root.components = [...context.components]
329329
root.directives = [...context.directives]
330330
root.imports = context.imports

packages/compiler-sfc/src/compileScript.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,7 +1561,7 @@ export function compileScript(
15611561
// avoid duplicated unref import
15621562
// as this may get injected by the render function preamble OR the
15631563
// css vars codegen
1564-
if (ast && ast.helpers.includes(UNREF)) {
1564+
if (ast && ast.helpers.has(UNREF)) {
15651565
helperImports.delete('unref')
15661566
}
15671567
returned = code

packages/compiler-ssr/__tests__/ssrInjectCssVars.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ describe('ssr: inject <style vars>', () => {
127127
}"
128128
`)
129129
expect(result.ast.helpers).toMatchInlineSnapshot(`
130-
Array [
130+
Set {
131131
Symbol(mergeProps),
132132
Symbol(unref),
133-
]
133+
}
134134
`)
135135
})
136136
})

packages/compiler-ssr/src/ssrCodegenTransform.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function ssrCodegenTransform(ast: RootNode, options: CompilerOptions) {
4949
createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`])
5050
)
5151
Array.from(cssContext.helpers.keys()).forEach(helper => {
52-
if (!ast.helpers.includes(helper)) ast.helpers.push(helper)
52+
ast.helpers.add(helper)
5353
})
5454
}
5555

@@ -61,10 +61,13 @@ export function ssrCodegenTransform(ast: RootNode, options: CompilerOptions) {
6161
// Finalize helpers.
6262
// We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
6363
ast.ssrHelpers = Array.from(
64-
new Set([...ast.helpers.filter(h => h in ssrHelpers), ...context.helpers])
64+
new Set([
65+
...Array.from(ast.helpers).filter(h => h in ssrHelpers),
66+
...context.helpers
67+
])
6568
)
6669

67-
ast.helpers = ast.helpers.filter(h => !(h in ssrHelpers))
70+
ast.helpers = new Set(Array.from(ast.helpers).filter(h => !(h in ssrHelpers)))
6871
}
6972

7073
export type SSRTransformContext = ReturnType<typeof createSSRTransformContext>

0 commit comments

Comments
 (0)