From 9daef5460cdf50d32926f806a5e9bcb05f12b720 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Wed, 18 Dec 2024 23:01:26 +0800 Subject: [PATCH] refactor(language-core): optimize codegen size of scoped classes --- .../lib/codegen/script/template.ts | 91 ++++++++++--------- .../lib/codegen/template/index.ts | 4 +- .../codegen/template/styleScopedClasses.ts | 18 ++-- .../tsc/passedFixtures/#3688/main.vue | 2 +- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index 348e1f0dd5..78c937d392 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -3,11 +3,28 @@ import type { Code } from '../../types'; import { getSlotsPropertyName, hyphenateTag } from '../../utils/shared'; import { TemplateCodegenContext, createTemplateCodegenContext } from '../template/context'; import { generateInterpolation } from '../template/interpolation'; -import { generateStyleScopedClasses } from '../template/styleScopedClasses'; +import { generateStyleScopedClassReferences } from '../template/styleScopedClasses'; import { endOfLine, newLine } from '../utils'; import type { ScriptCodegenContext } from './context'; import { codeFeatures, type ScriptCodegenOptions } from './index'; +export function* generateTemplate( + options: ScriptCodegenOptions, + ctx: ScriptCodegenContext +): Generator { + ctx.generatedTemplate = true; + + const templateCodegenCtx = createTemplateCodegenContext({ + scriptSetupBindingNames: new Set(), + edited: options.edited, + }); + yield* generateTemplateCtx(options); + yield* generateTemplateComponents(options); + yield* generateTemplateDirectives(options); + yield* generateTemplateBody(options, templateCodegenCtx); + return templateCodegenCtx; +} + function* generateTemplateCtx(options: ScriptCodegenOptions): Generator { const exps = []; @@ -107,36 +124,50 @@ export function* generateTemplateDirectives(options: ScriptCodegenOptions): Gene yield `let __VLS_directives!: typeof __VLS_localDirectives & __VLS_GlobalDirectives${endOfLine}`; } -export function* generateTemplate( +function* generateTemplateBody( options: ScriptCodegenOptions, - ctx: ScriptCodegenContext -): Generator { - ctx.generatedTemplate = true; + templateCodegenCtx: TemplateCodegenContext +): Generator { + yield* generateStyleScopedClasses(options, templateCodegenCtx); + yield* generateStyleScopedClassReferences(templateCodegenCtx, true); + yield* generateCssVars(options, templateCodegenCtx); - const templateCodegenCtx = createTemplateCodegenContext({ - scriptSetupBindingNames: new Set(), - edited: options.edited, - }); - yield* generateTemplateCtx(options); - yield* generateTemplateComponents(options); - yield* generateTemplateDirectives(options); - yield* generateTemplateBody(options, templateCodegenCtx); - return templateCodegenCtx; + if (options.templateCodegen) { + for (const code of options.templateCodegen.codes) { + yield code; + } + } + else { + yield `// no template${newLine}`; + if (!options.scriptSetupRanges?.defineSlots) { + yield `const __VLS_slots = {}${endOfLine}`; + } + yield `const __VLS_inheritedAttrs = {}${endOfLine}`; + yield `const $refs = {}${endOfLine}`; + yield `const $el = {} as any${endOfLine}`; + } + + yield `return {${newLine}`; + yield ` attrs: {} as Partial,${newLine}`; + yield ` slots: ${options.scriptSetupRanges?.defineSlots?.name ?? '__VLS_slots'},${newLine}`; + yield ` refs: $refs,${newLine}`; + yield ` rootEl: $el,${newLine}`; + yield `}${endOfLine}`; } -function* generateTemplateBody( +function* generateStyleScopedClasses( options: ScriptCodegenOptions, - templateCodegenCtx: TemplateCodegenContext + ctx: TemplateCodegenContext ): Generator { const firstClasses = new Set(); - yield `let __VLS_styleScopedClasses!: {}`; + yield `type __VLS_StyleScopedClasses = {}`; for (let i = 0; i < options.sfc.styles.length; i++) { const style = options.sfc.styles[i]; const option = options.vueCompilerOptions.experimentalResolveStyleCssClasses; if (option === 'always' || (option === 'scoped' && style.scoped)) { for (const className of style.classNames) { if (firstClasses.has(className.text)) { - templateCodegenCtx.scopedClasses.push({ + ctx.scopedClasses.push({ source: 'style_' + i, className: className.text.slice(1), offset: className.offset + 1 @@ -155,30 +186,6 @@ function* generateTemplateBody( } } yield endOfLine; - yield* generateStyleScopedClasses(templateCodegenCtx, true); - yield* generateCssVars(options, templateCodegenCtx); - - if (options.templateCodegen) { - for (const code of options.templateCodegen.codes) { - yield code; - } - } - else { - yield `// no template${newLine}`; - if (!options.scriptSetupRanges?.defineSlots) { - yield `const __VLS_slots = {}${endOfLine}`; - } - yield `const __VLS_inheritedAttrs = {}${endOfLine}`; - yield `const $refs = {}${endOfLine}`; - yield `const $el = {} as any${endOfLine}`; - } - - yield `return {${newLine}`; - yield ` attrs: {} as Partial,${newLine}`; - yield ` slots: ${options.scriptSetupRanges?.defineSlots?.name ?? '__VLS_slots'},${newLine}`; - yield ` refs: $refs,${newLine}`; - yield ` rootEl: $el,${newLine}`; - yield `}${endOfLine}`; } export function* generateCssClassProperty( diff --git a/packages/language-core/lib/codegen/template/index.ts b/packages/language-core/lib/codegen/template/index.ts index 4818b253e1..1edad7e844 100644 --- a/packages/language-core/lib/codegen/template/index.ts +++ b/packages/language-core/lib/codegen/template/index.ts @@ -7,7 +7,7 @@ import { generateStringLiteralKey } from '../utils/stringLiteralKey'; import { TemplateCodegenContext, createTemplateCodegenContext } from './context'; import { getCanonicalComponentName, getPossibleOriginalComponentNames } from './element'; import { generateObjectProperty } from './objectProperty'; -import { generateStyleScopedClasses } from './styleScopedClasses'; +import { generateStyleScopedClassReferences } from './styleScopedClasses'; import { generateTemplateChild, getVForNode } from './templateChild'; export interface TemplateCodegenOptions { @@ -46,7 +46,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator { + if (!ctx.emptyClassOffsets.length && !ctx.scopedClasses.length) { + return; + } + + yield `[`; for (const offset of ctx.emptyClassOffsets) { - yield `__VLS_styleScopedClasses['`; + yield `'`; yield [ '', 'template', offset, ctx.codeFeatures.additionalCompletion, ]; - yield `']${endOfLine}`; + yield `', `; } for (const { source, className, offset } of ctx.scopedClasses) { - yield `__VLS_styleScopedClasses[`; yield [ '', source, @@ -35,9 +39,9 @@ export function* generateStyleScopedClasses( offset + className.length, ctx.codeFeatures.navigationWithoutRename, ]; - yield `]${endOfLine}`; + yield `, `; } - yield newLine; + yield `] as (keyof __VLS_StyleScopedClasses)[]${endOfLine}`; function* escapeString(source: string, className: string, offset: number, escapeTargets: string[]): Generator { let count = 0; diff --git a/test-workspace/tsc/passedFixtures/#3688/main.vue b/test-workspace/tsc/passedFixtures/#3688/main.vue index 7fbf85ca0a..a225186021 100644 --- a/test-workspace/tsc/passedFixtures/#3688/main.vue +++ b/test-workspace/tsc/passedFixtures/#3688/main.vue @@ -1,6 +1,6 @@