diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index a481ddcf..3ca4b7de 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -66,7 +66,10 @@ export interface CodegenResult { } export interface CodegenContext - extends Omit, 'bindingMetadata' | 'inline'> { + extends Omit< + Required, + 'bindingMetadata' | 'inline' | 'isTS' + > { source: string code: string line: number @@ -214,29 +217,33 @@ export function generate( genFunctionPreamble(ast, preambleContext) } - // binding optimizations - const optimizeSources = - options.bindingMetadata && !options.inline - ? `, $props, $setup, $data, $options` - : `` + const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'] + if (!__BROWSER__ && options.bindingMetadata && !options.inline) { + // binding optimization args + args.push('$props', '$setup', '$data', '$options') + } + const signature = + !__BROWSER__ && options.isTS + ? args.map(arg => `${arg}: any`).join(',') + : args.join(',') // enter render function if (!ssr) { if (isSetupInlined) { if (genScopeId) { push(`${PURE_ANNOTATION}_withId(`) } - push(`(_ctx, _cache${optimizeSources}) => {`) + push(`(${signature}) => {`) } else { if (genScopeId) { push(`const render = ${PURE_ANNOTATION}_withId(`) } - push(`function render(_ctx, _cache${optimizeSources}) {`) + push(`function render(${signature}) {`) } } else { if (genScopeId) { push(`const ssrRender = ${PURE_ANNOTATION}_withId(`) } - push(`function ssrRender(_ctx, _push, _parent, _attrs${optimizeSources}) {`) + push(`function ssrRender(${signature}) {`) } indent() diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 43d019b7..02ee4068 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -124,6 +124,10 @@ interface SharedTransformCodegenOptions { * This allows the function to directly access setup() local bindings. */ inline?: boolean + /** + * Indicates that transforms and codegen should try to output valid TS code + */ + isTS?: boolean } export interface TransformOptions extends SharedTransformCodegenOptions { @@ -195,10 +199,6 @@ export interface TransformOptions extends SharedTransformCodegenOptions { * needed to render inline CSS variables on component root */ ssrCssVars?: string - /** - * Indicates that transforms should try to output valid TS code - */ - isTS?: boolean onError?: (error: CompilerError) => void } diff --git a/packages/compiler-core/src/transforms/transformExpression.ts b/packages/compiler-core/src/transforms/transformExpression.ts index edee2f52..4ad7d888 100644 --- a/packages/compiler-core/src/transforms/transformExpression.ts +++ b/packages/compiler-core/src/transforms/transformExpression.ts @@ -118,38 +118,32 @@ export function processExpression( // setup inline mode if (type === BindingTypes.SETUP_CONST) { return raw - } else if (type === BindingTypes.SETUP_REF) { + } else if ( + type === BindingTypes.SETUP_REF || + type === BindingTypes.SETUP_MAYBE_REF + ) { + // const binding that may or may not be ref + // if it's not a ref, then assignments don't make sense - + // so we ignore the non-ref assignment case and generate code + // that assumes the value to be a ref for more efficiency return isAssignmentLVal || isUpdateArg ? `${raw}.value` : `${context.helperString(UNREF)}(${raw})` - } else if ( - type === BindingTypes.SETUP_MAYBE_REF || - type === BindingTypes.SETUP_LET - ) { + } else if (type === BindingTypes.SETUP_LET) { if (isAssignmentLVal) { - if (type === BindingTypes.SETUP_MAYBE_REF) { - // const binding that may or may not be ref - // if it's not a ref, then the assignment doesn't make sense so - // just no-op it - // x = y ---> !isRef(x) ? null : x.value = y - return `!${context.helperString( - IS_REF - )}(${raw}) ? null : ${raw}.value` - } else { - // let binding. - // this is a bit more tricky as we need to cover the case where - // let is a local non-ref value, and we need to replicate the - // right hand side value. - // x = y --> isRef(x) ? x.value = y : x = y - const rVal = (parent as AssignmentExpression).right - const rExp = rawExp.slice(rVal.start! - 1, rVal.end! - 1) - const rExpString = stringifyExpression( - processExpression(createSimpleExpression(rExp, false), context) - ) - return `${context.helperString(IS_REF)}(${raw})${ - context.isTS ? ` //@ts-ignore\n` : `` - } ? ${raw}.value = ${rExpString} : ${raw}` - } + // let binding. + // this is a bit more tricky as we need to cover the case where + // let is a local non-ref value, and we need to replicate the + // right hand side value. + // x = y --> isRef(x) ? x.value = y : x = y + const rVal = (parent as AssignmentExpression).right + const rExp = rawExp.slice(rVal.start! - 1, rVal.end! - 1) + const rExpString = stringifyExpression( + processExpression(createSimpleExpression(rExp, false), context) + ) + return `${context.helperString(IS_REF)}(${raw})${ + context.isTS ? ` //@ts-ignore\n` : `` + } ? ${raw}.value = ${rExpString} : ${raw}` } else if (isUpdateArg) { // make id replace parent in the code range so the raw update operator // is removed @@ -158,21 +152,11 @@ export function processExpression( const { prefix: isPrefix, operator } = parent as UpdateExpression const prefix = isPrefix ? operator : `` const postfix = isPrefix ? `` : operator - if (type === BindingTypes.SETUP_MAYBE_REF) { - // const binding that may or may not be ref - // if it's not a ref, then the assignment doesn't make sense so - // just no-op it - // x++ ---> !isRef(x) ? null : x.value++ - return `!${context.helperString( - IS_REF - )}(${raw}) ? null : ${prefix}${raw}.value${postfix}` - } else { - // let binding. - // x++ --> isRef(a) ? a.value++ : a++ - return `${context.helperString(IS_REF)}(${raw})${ - context.isTS ? ` //@ts-ignore\n` : `` - } ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}` - } + // let binding. + // x++ --> isRef(a) ? a.value++ : a++ + return `${context.helperString(IS_REF)}(${raw})${ + context.isTS ? ` //@ts-ignore\n` : `` + } ? ${prefix}${raw}.value${postfix} : ${prefix}${raw}${postfix}` } else { return `${context.helperString(UNREF)}(${raw})` } diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index ce506aa3..00db3268 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -124,7 +124,9 @@ export const transformOn: DirectiveTransform = ( exp = createCompoundExpression([ `${ isInlineStatement - ? `$event` + ? !__BROWSER__ && context.isTS + ? `($event: any)` + : `$event` : `${ !__BROWSER__ && context.isTS ? `\n//@ts-ignore\n` : `` }(...args)` diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index 6f137ac3..c05ddbac 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -1,5 +1,4 @@ import { - ComponentPublicInstance, getCurrentInstance, onMounted, warn, @@ -14,9 +13,7 @@ import { ShapeFlags } from '@vue/shared' * Runtime helper for SFC's CSS variable injection feature. * @private */ -export function useCssVars( - getter: (ctx: ComponentPublicInstance) => Record -) { +export function useCssVars(getter: (ctx: any) => Record) { const instance = getCurrentInstance() /* istanbul ignore next */ if (!instance) {