]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(compiler-vapor): codegen result
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Sat, 27 Jan 2024 13:42:52 +0000 (21:42 +0800)
committer三咲智子 Kevin Deng <sxzz@sxzz.moe>
Sat, 27 Jan 2024 14:00:34 +0000 (22:00 +0800)
12 files changed:
packages/compiler-core/src/codegen.ts
packages/compiler-core/src/index.ts
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/compileTemplate.ts
packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts
packages/compiler-vapor/__tests__/transforms/vOn.spec.ts
packages/compiler-vapor/__tests__/transforms/vOnce.spec.ts
packages/compiler-vapor/__tests__/transforms/vText.spec.ts
packages/compiler-vapor/src/compile.ts
packages/compiler-vapor/src/generate.ts
packages/compiler-vapor/src/ir.ts
packages/compiler-vapor/src/transform.ts

index 821c85d4cf2e29d018d50184fe595e2e5f16aaaf..81b512d892c3dd5444195daae19c7058d6851ad4 100644 (file)
@@ -62,11 +62,17 @@ const aliasHelper = (s: symbol) => `${helperNameMap[s]}: _${helperNameMap[s]}`
 
 type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode
 
-export interface CodegenResult {
+export interface BaseCodegenResult {
   code: string
   preamble: string
-  ast: RootNode
+  ast: unknown
   map?: RawSourceMap
+  helpers?: Set<string> | Set<symbol>
+}
+
+export interface CodegenResult extends BaseCodegenResult {
+  ast: RootNode
+  helpers: Set<symbol>
 }
 
 export enum NewlineType {
@@ -359,6 +365,7 @@ export function generate(
     code: context.code,
     preamble: isSetupInlined ? preambleContext.code : ``,
     map: context.map ? context.map.toJSON() : undefined,
+    helpers: ast.helpers,
   }
 }
 
index 4fdcd4052c0249423492cf323b218b71a31bcfb6..aff69dbc74ba343dbd9d8f1cff25b8f9dc60695d 100644 (file)
@@ -26,6 +26,7 @@ export {
   NewlineType,
   type CodegenContext,
   type CodegenResult,
+  type BaseCodegenResult,
 } from './codegen'
 export {
   ErrorCodes,
index 3d1667e6cfabaffd9a2e70d8646af81cc56bbfdf..522d2c204f75a423246a03f9c29d7e51921d2404 100644 (file)
@@ -846,7 +846,7 @@ export function compileScript(
       }
       // inline render function mode - we are going to compile the template and
       // inline it right here
-      const { code, ast, preamble, tips, errors } = compileTemplate({
+      const { code, preamble, tips, errors, helpers } = compileTemplate({
         filename,
         ast: sfc.template.ast,
         source: sfc.template.content,
@@ -891,7 +891,7 @@ export function compileScript(
       // avoid duplicated unref import
       // as this may get injected by the render function preamble OR the
       // css vars codegen
-      if (ast && ast.helpers.has(UNREF)) {
+      if (helpers && helpers.has(UNREF)) {
         ctx.helperImports.delete('unref')
       }
       returned = code
index 65e9bd501189a7182987c4029779c3f2b50ff915..957269e01103bc1996bbd406a299d38b12873551 100644 (file)
@@ -1,5 +1,5 @@
 import {
-  type CodegenResult,
+  type BaseCodegenResult,
   type CompilerError,
   type CompilerOptions,
   type ElementNode,
@@ -34,18 +34,22 @@ import { warnOnce } from './warn'
 import { genCssVarsFromList } from './style/cssVars'
 
 export interface TemplateCompiler {
-  compile(source: string | RootNode, options: CompilerOptions): CodegenResult
+  compile(
+    source: string | RootNode,
+    options: CompilerOptions,
+  ): BaseCodegenResult
   parse(template: string, options: ParserOptions): RootNode
 }
 
 export interface SFCTemplateCompileResults {
   code: string
-  ast?: RootNode
+  ast?: unknown
   preamble?: string
   source: string
   tips: string[]
   errors: (string | CompilerError)[]
   map?: RawSourceMap
+  helpers?: Set<string | symbol>
 }
 
 export interface SFCTemplateCompileOptions {
@@ -238,25 +242,30 @@ function doCompileTemplate({
     inAST = createRoot(template.children, inAST.source)
   }
 
-  let { code, ast, preamble, map } = compiler.compile(inAST || source, {
-    mode: 'module',
-    prefixIdentifiers: true,
-    hoistStatic: true,
-    cacheHandlers: true,
-    ssrCssVars:
-      ssr && ssrCssVars && ssrCssVars.length
-        ? genCssVarsFromList(ssrCssVars, shortId, isProd, true)
-        : '',
-    scopeId: scoped ? longId : undefined,
-    slotted,
-    sourceMap: true,
-    ...compilerOptions,
-    hmr: !isProd,
-    nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []),
-    filename,
-    onError: e => errors.push(e),
-    onWarn: w => warnings.push(w),
-  })
+  let { code, ast, preamble, map, helpers } = compiler.compile(
+    inAST || source,
+    {
+      mode: 'module',
+      prefixIdentifiers: true,
+      hoistStatic: true,
+      cacheHandlers: true,
+      ssrCssVars:
+        ssr && ssrCssVars && ssrCssVars.length
+          ? genCssVarsFromList(ssrCssVars, shortId, isProd, true)
+          : '',
+      scopeId: scoped ? longId : undefined,
+      slotted,
+      sourceMap: true,
+      ...compilerOptions,
+      hmr: !isProd,
+      nodeTransforms: nodeTransforms.concat(
+        compilerOptions.nodeTransforms || [],
+      ),
+      filename,
+      onError: e => errors.push(e),
+      onWarn: w => warnings.push(w),
+    },
+  )
 
   // inMap should be the map produced by ./parse.ts which is a simple line-only
   // mapping. If it is present, we need to adjust the final map and errors to
@@ -282,7 +291,16 @@ function doCompileTemplate({
     return msg
   })
 
-  return { code, ast, preamble, source, errors, tips, map }
+  return {
+    code,
+    ast,
+    preamble,
+    source,
+    errors,
+    tips,
+    map,
+    helpers,
+  }
 }
 
 function mapLines(oldMap: RawSourceMap, newMap: RawSourceMap): RawSourceMap {
index 8614c141bd5cd9c12cf0a948c86c224e5c30b802..bebc1a8007061c82f87457c6ca269ead6d7a37a7 100644 (file)
@@ -7,20 +7,13 @@ import {
 import {
   type CompilerOptions,
   IRNodeTypes,
-  type RootIRNode,
   compile as _compile,
   generate,
   transform,
 } from '../../src'
 import { getBaseTransformPreset } from '../../src/compile'
 
-function compileWithVHtml(
-  template: string,
-  options: CompilerOptions = {},
-): {
-  ir: RootIRNode
-  code: string
-} {
+function compileWithVHtml(template: string, options: CompilerOptions = {}) {
   const ast = parse(template, { prefixIdentifiers: true, ...options })
   const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(true)
   const ir = transform(ast, {
@@ -29,20 +22,26 @@ function compileWithVHtml(
     prefixIdentifiers: true,
     ...options,
   })
-  const { code } = generate(ir, { prefixIdentifiers: true, ...options })
-  return { ir, code }
+  const { code, helpers, vaporHelpers } = generate(ir, {
+    prefixIdentifiers: true,
+    ...options,
+  })
+  return { ir, code, helpers, vaporHelpers }
 }
 
 describe('v-html', () => {
   test('should convert v-html to innerHTML', () => {
-    const { code, ir } = compileWithVHtml(`<div v-html="code"></div>`, {
-      bindingMetadata: {
-        code: BindingTypes.SETUP_REF,
+    const { code, ir, helpers, vaporHelpers } = compileWithVHtml(
+      `<div v-html="code"></div>`,
+      {
+        bindingMetadata: {
+          code: BindingTypes.SETUP_REF,
+        },
       },
-    })
+    )
 
-    expect(ir.vaporHelpers).contains('setHtml')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('setHtml')
+    expect(helpers.size).toBe(0)
 
     expect(ir.operation).toEqual([])
     expect(ir.effect).toMatchObject([
@@ -73,12 +72,15 @@ describe('v-html', () => {
 
   test('should raise error and ignore children when v-html is present', () => {
     const onError = vi.fn()
-    const { code, ir } = compileWithVHtml(`<div v-html="test">hello</div>`, {
-      onError,
-    })
+    const { code, ir, helpers, vaporHelpers } = compileWithVHtml(
+      `<div v-html="test">hello</div>`,
+      {
+        onError,
+      },
+    )
 
-    expect(ir.vaporHelpers).contains('setHtml')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('setHtml')
+    expect(helpers.size).toBe(0)
 
     // children should have been removed
     expect(ir.template).toMatchObject([{ template: '<div></div>' }])
index 7705e1e1837f4681a6de235a11d5ac72c590ea90..3b2d0c626f96093b6493a34bd9b596e330963f00 100644 (file)
@@ -2,7 +2,6 @@ import { BindingTypes, ErrorCodes, NodeTypes, parse } from '@vue/compiler-dom'
 import {
   type CompilerOptions,
   IRNodeTypes,
-  type RootIRNode,
   compile as _compile,
   generate,
   transform,
@@ -11,13 +10,7 @@ import {
 import { transformVOn } from '../../src/transforms/vOn'
 import { transformElement } from '../../src/transforms/transformElement'
 
-function compileWithVOn(
-  template: string,
-  options: CompilerOptions = {},
-): {
-  ir: RootIRNode
-  code: string
-} {
+function compileWithVOn(template: string, options: CompilerOptions = {}) {
   const ast = parse(template, { prefixIdentifiers: true, ...options })
   const ir = transform(ast, {
     nodeTransforms: [transformElement],
@@ -27,20 +20,26 @@ function compileWithVOn(
     prefixIdentifiers: true,
     ...options,
   })
-  const { code } = generate(ir, { prefixIdentifiers: true, ...options })
-  return { ir, code }
+  const { code, helpers, vaporHelpers } = generate(ir, {
+    prefixIdentifiers: true,
+    ...options,
+  })
+  return { ir, code, helpers, vaporHelpers }
 }
 
 describe('v-on', () => {
   test('simple expression', () => {
-    const { code, ir } = compileWithVOn(`<div @click="handleClick"></div>`, {
-      bindingMetadata: {
-        handleClick: BindingTypes.SETUP_CONST,
+    const { code, ir, helpers, vaporHelpers } = compileWithVOn(
+      `<div @click="handleClick"></div>`,
+      {
+        bindingMetadata: {
+          handleClick: BindingTypes.SETUP_CONST,
+        },
       },
-    })
+    )
 
-    expect(ir.vaporHelpers).contains('on')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('on')
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toEqual([])
 
     expect(ir.operation).toMatchObject([
@@ -99,11 +98,13 @@ describe('v-on', () => {
   })
 
   test('dynamic arg', () => {
-    const { code, ir } = compileWithVOn(`<div v-on:[event]="handler"/>`)
+    const { code, ir, helpers, vaporHelpers } = compileWithVOn(
+      `<div v-on:[event]="handler"/>`,
+    )
 
-    expect(ir.vaporHelpers).contains('on')
-    expect(ir.vaporHelpers).contains('renderEffect')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('on')
+    expect(vaporHelpers).contains('renderEffect')
+    expect(helpers.size).toBe(0)
     expect(ir.operation).toEqual([])
 
     expect(ir.effect[0].operations[0]).toMatchObject({
@@ -133,13 +134,16 @@ describe('v-on', () => {
   })
 
   test('dynamic arg with complex exp prefixing', () => {
-    const { ir, code } = compileWithVOn(`<div v-on:[event(foo)]="handler"/>`, {
-      prefixIdentifiers: true,
-    })
+    const { ir, code, helpers, vaporHelpers } = compileWithVOn(
+      `<div v-on:[event(foo)]="handler"/>`,
+      {
+        prefixIdentifiers: true,
+      },
+    )
 
-    expect(ir.vaporHelpers).contains('on')
-    expect(ir.vaporHelpers).contains('renderEffect')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('on')
+    expect(vaporHelpers).contains('renderEffect')
+    expect(helpers.size).toBe(0)
     expect(ir.operation).toEqual([])
 
     expect(ir.effect[0].operations[0]).toMatchObject({
@@ -161,10 +165,11 @@ describe('v-on', () => {
   })
 
   test('should wrap as function if expression is inline statement', () => {
-    const { code, ir } = compileWithVOn(`<div @click="i++"/>`)
+    const { code, ir, helpers, vaporHelpers } =
+      compileWithVOn(`<div @click="i++"/>`)
 
-    expect(ir.vaporHelpers).contains('on')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('on')
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toEqual([])
 
     expect(ir.operation).toMatchObject([
@@ -395,10 +400,12 @@ describe('v-on', () => {
   })
 
   test('case conversion for kebab-case events', () => {
-    const { ir, code } = compileWithVOn(`<div v-on:foo-bar="onMount"/>`)
+    const { ir, code, helpers, vaporHelpers } = compileWithVOn(
+      `<div v-on:foo-bar="onMount"/>`,
+    )
 
-    expect(ir.vaporHelpers).contains('on')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('on')
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toEqual([])
 
     expect(ir.operation).toMatchObject([
@@ -443,15 +450,15 @@ describe('v-on', () => {
   test.todo('vue: prefixed events')
 
   test('should support multiple modifiers and event options w/ prefixIdentifiers: true', () => {
-    const { code, ir } = compileWithVOn(
+    const { code, ir, vaporHelpers } = compileWithVOn(
       `<div @click.stop.prevent.capture.once="test"/>`,
       {
         prefixIdentifiers: true,
       },
     )
 
-    expect(ir.vaporHelpers).contains('on')
-    expect(ir.vaporHelpers).contains('withModifiers')
+    expect(vaporHelpers).contains('on')
+    expect(vaporHelpers).contains('withModifiers')
 
     expect(ir.operation).toMatchObject([
       {
index d22297a1d67a6cc48fafbe18f095fb40bfb0a3dd..d905f3957a0c6463bd2fe87396d5b679c54e580b 100644 (file)
@@ -2,20 +2,13 @@ import { BindingTypes, NodeTypes, parse } from '@vue/compiler-dom'
 import {
   type CompilerOptions,
   IRNodeTypes,
-  type RootIRNode,
   compile as _compile,
   generate as generate,
   transform,
 } from '../../src'
 import { getBaseTransformPreset } from '../../src/compile'
 
-function compileWithOnce(
-  template: string,
-  options: CompilerOptions = {},
-): {
-  ir: RootIRNode
-  code: string
-} {
+function compileWithOnce(template: string, options: CompilerOptions = {}) {
   const ast = parse(template, { prefixIdentifiers: true, ...options })
   const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(true)
   const ir = transform(ast, {
@@ -24,13 +17,16 @@ function compileWithOnce(
     prefixIdentifiers: true,
     ...options,
   })
-  const { code } = generate(ir, { prefixIdentifiers: true, ...options })
-  return { ir, code }
+  const { code, helpers, vaporHelpers } = generate(ir, {
+    prefixIdentifiers: true,
+    ...options,
+  })
+  return { ir, code, helpers, vaporHelpers }
 }
 
 describe('compiler: v-once', () => {
   test('basic', () => {
-    const { ir, code } = compileWithOnce(
+    const { ir, code, helpers } = compileWithOnce(
       `<div v-once>
         {{ msg }}
         <span :class="clz" />
@@ -42,7 +38,7 @@ describe('compiler: v-once', () => {
         },
       },
     )
-    expect(ir.helpers.size).toBe(0)
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toEqual([])
 
     expect(ir.operation).toMatchObject([
@@ -89,9 +85,9 @@ describe('compiler: v-once', () => {
   })
 
   test('as root node', () => {
-    const { ir, code } = compileWithOnce(`<div :id="foo" v-once />`)
+    const { ir, code, helpers } = compileWithOnce(`<div :id="foo" v-once />`)
 
-    expect(ir.helpers.size).toBe(0)
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toEqual([])
 
     expect(ir.operation).toMatchObject([
@@ -116,8 +112,10 @@ describe('compiler: v-once', () => {
   })
 
   test('on nested plain element', () => {
-    const { ir, code } = compileWithOnce(`<div><div :id="foo" v-once /></div>`)
-    expect(ir.helpers.size).toBe(0)
+    const { ir, code, helpers } = compileWithOnce(
+      `<div><div :id="foo" v-once /></div>`,
+    )
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toEqual([])
 
     expect(ir.operation).toMatchObject([
@@ -145,8 +143,10 @@ describe('compiler: v-once', () => {
   test.todo('on slot outlet')
 
   test('inside v-once', () => {
-    const { ir, code } = compileWithOnce(`<div v-once><div v-once/></div>`)
-    expect(ir.helpers.size).toBe(0)
+    const { ir, code, helpers } = compileWithOnce(
+      `<div v-once><div v-once/></div>`,
+    )
+    expect(helpers.size).toBe(0)
     expect(ir.effect).toMatchObject([])
     expect(ir.operation).toMatchObject([])
 
index 2e7656671ebfd6792658e9df8fe4f7eb67411564..d103f3f1fe4c487e111ea6cb87e634e88f9d0fe0 100644 (file)
@@ -7,20 +7,13 @@ import {
 import {
   type CompilerOptions,
   IRNodeTypes,
-  type RootIRNode,
   compile as _compile,
   generate,
   transform,
 } from '../../src'
 import { getBaseTransformPreset } from '../../src/compile'
 
-function compileWithVText(
-  template: string,
-  options: CompilerOptions = {},
-): {
-  ir: RootIRNode
-  code: string
-} {
+function compileWithVText(template: string, options: CompilerOptions = {}) {
   const ast = parse(template, { prefixIdentifiers: true, ...options })
   const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(true)
   const ir = transform(ast, {
@@ -29,20 +22,26 @@ function compileWithVText(
     prefixIdentifiers: true,
     ...options,
   })
-  const { code } = generate(ir, { prefixIdentifiers: true, ...options })
-  return { ir, code }
+  const { code, helpers, vaporHelpers } = generate(ir, {
+    prefixIdentifiers: true,
+    ...options,
+  })
+  return { ir, code, helpers, vaporHelpers }
 }
 
 describe('v-text', () => {
   test('should convert v-text to textContent', () => {
-    const { code, ir } = compileWithVText(`<div v-text="str"></div>`, {
-      bindingMetadata: {
-        str: BindingTypes.SETUP_REF,
+    const { code, ir, helpers, vaporHelpers } = compileWithVText(
+      `<div v-text="str"></div>`,
+      {
+        bindingMetadata: {
+          str: BindingTypes.SETUP_REF,
+        },
       },
-    })
+    )
 
-    expect(ir.vaporHelpers).contains('setText')
-    expect(ir.helpers.size).toBe(0)
+    expect(vaporHelpers).contains('setText')
+    expect(helpers.size).toBe(0)
 
     expect(ir.operation).toEqual([])
 
index d271cc1bbcc978bcee201009d0720d4d24878a57..f25e6f5a4661cad8117f800afa708c5b0742f18b 100644 (file)
@@ -1,6 +1,5 @@
 import {
   type CompilerOptions as BaseCompilerOptions,
-  type CodegenResult,
   ErrorCodes,
   type RootNode,
   createCompilerError,
@@ -13,7 +12,7 @@ import {
   type NodeTransform,
   transform,
 } from './transform'
-import { generate } from './generate'
+import { type VaporCodegenResult, generate } from './generate'
 import { transformOnce } from './transforms/vOnce'
 import { transformElement } from './transforms/transformElement'
 import { transformVHtml } from './transforms/vHtml'
@@ -33,7 +32,7 @@ export type CompilerOptions = HackOptions<BaseCompilerOptions>
 export function compile(
   source: string | RootNode,
   options: CompilerOptions = {},
-): CodegenResult {
+): VaporCodegenResult {
   const onError = options.onError || defaultOnError
   const isModuleMode = options.mode === 'module'
   /* istanbul ignore if */
index 4022c5a6c556409be948260db5c33e5f048d6563..1352fba7d70e7a654f51ca642ac86b92be1aeba6 100644 (file)
@@ -1,6 +1,6 @@
 import {
   type CodegenOptions as BaseCodegenOptions,
-  type CodegenResult,
+  type BaseCodegenResult,
   NewlineType,
   type Position,
   type SourceLocation,
@@ -90,7 +90,8 @@ function createCodegenContext(
     expressionPlugins = [],
   }: CodegenOptions,
 ) {
-  const { helpers, vaporHelpers } = ir
+  const helpers = new Set<string>([])
+  const vaporHelpers = new Set<string>([])
   const context: CodegenContext = {
     mode,
     prefixIdentifiers,
@@ -227,11 +228,17 @@ function createCodegenContext(
   return context
 }
 
+export interface VaporCodegenResult extends BaseCodegenResult {
+  ast: RootIRNode
+  helpers: Set<string>
+  vaporHelpers: Set<string>
+}
+
 // IR -> JS codegen
 export function generate(
   ir: RootIRNode,
   options: CodegenOptions = {},
-): CodegenResult {
+): VaporCodegenResult {
   const ctx = createCodegenContext(ir, options)
   const {
     push,
@@ -333,9 +340,11 @@ export function generate(
 
   return {
     code: ctx.code,
-    ast: ir as any,
+    ast: ir,
     preamble,
     map: ctx.map ? ctx.map.toJSON() : undefined,
+    helpers,
+    vaporHelpers,
   }
 }
 
index 1c2f6ee308a65a79d143ef681fa983eff80059f1..708262d7228718dd7b1015204d6b47fddf433652 100644 (file)
@@ -45,8 +45,6 @@ export interface RootIRNode extends BaseIRNode {
   dynamic: IRDynamicInfo
   effect: IREffect[]
   operation: OperationNode[]
-  helpers: Set<string>
-  vaporHelpers: Set<VaporHelper>
 }
 
 export interface TemplateFactoryIRNode extends BaseIRNode {
index eb230da76784a9e44f257aa79e2693d4feac5428..f0f311a7d8a23d47c7940041ea34b2254fe4182f 100644 (file)
@@ -56,7 +56,30 @@ export interface TransformContext<T extends AllNode = AllNode> {
     operation: OperationNode[],
   ): void
   registerOperation(...operations: OperationNode[]): void
-  helper(name: string): string
+}
+
+const defaultOptions = {
+  filename: '',
+  prefixIdentifiers: false,
+  hoistStatic: false,
+  hmr: false,
+  cacheHandlers: false,
+  nodeTransforms: [],
+  directiveTransforms: {},
+  transformHoist: null,
+  isBuiltInComponent: NOOP,
+  isCustomElement: NOOP,
+  expressionPlugins: [],
+  scopeId: null,
+  slotted: true,
+  ssr: false,
+  inSSR: false,
+  ssrCssVars: ``,
+  bindingMetadata: EMPTY_OBJ,
+  inline: false,
+  isTS: false,
+  onError: defaultOnError,
+  onWarn: defaultOnWarn,
 }
 
 // TODO use class for better perf
@@ -66,40 +89,14 @@ function createRootContext(
   options: TransformOptions = {},
 ): TransformContext<RootNode> {
   let globalId = 0
-  const { effect, operation: operation, helpers, vaporHelpers } = ir
+  const { effect, operation: operation } = ir
 
   const ctx: TransformContext<RootNode> = {
     node,
     parent: null,
     index: 0,
     root: null!, // set later
-    options: extend(
-      {},
-      {
-        filename: '',
-        prefixIdentifiers: false,
-        hoistStatic: false,
-        hmr: false,
-        cacheHandlers: false,
-        nodeTransforms: [],
-        directiveTransforms: {},
-        transformHoist: null,
-        isBuiltInComponent: NOOP,
-        isCustomElement: NOOP,
-        expressionPlugins: [],
-        scopeId: null,
-        slotted: true,
-        ssr: false,
-        inSSR: false,
-        ssrCssVars: ``,
-        bindingMetadata: EMPTY_OBJ,
-        inline: false,
-        isTS: false,
-        onError: defaultOnError,
-        onWarn: defaultOnWarn,
-      },
-      options,
-    ),
+    options: extend({}, defaultOptions, options),
     dynamic: ir.dynamic,
     inVOnce: false,
 
@@ -162,11 +159,6 @@ function createRootContext(
     registerOperation(...node) {
       operation.push(...node)
     },
-    // TODO not used yet
-    helper(name, vapor = true) {
-      ;(vapor ? vaporHelpers : helpers).add(name)
-      return name
-    },
   }
   ctx.root = ctx
   ctx.reference()
@@ -216,8 +208,6 @@ export function transform(
     },
     effect: [],
     operation: [],
-    helpers: new Set([]),
-    vaporHelpers: new Set([]),
   }
 
   const ctx = createRootContext(ir, root, options)