fix: ensure backwards compat for pre-compiled sfc components

fix #3493
This commit is contained in:
Evan You
2021-03-27 10:53:45 -04:00
parent 9ff70be2b3
commit 37c17091fd
16 changed files with 278 additions and 96 deletions

View File

@@ -43,7 +43,9 @@ import {
SET_BLOCK_TRACKING,
CREATE_COMMENT,
CREATE_TEXT,
SET_SCOPE_ID,
PUSH_SCOPE_ID,
POP_SCOPE_ID,
WITH_SCOPE_ID,
WITH_DIRECTIVES,
CREATE_BLOCK,
OPEN_BLOCK,
@@ -53,6 +55,7 @@ import {
import { ImportItem } from './transform'
const PURE_ANNOTATION = `/*#__PURE__*/`
const WITH_ID = `_withId`
type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode
@@ -195,11 +198,13 @@ export function generate(
indent,
deindent,
newline,
scopeId,
ssr
} = context
const hasHelpers = ast.helpers.length > 0
const useWithBlock = !prefixIdentifiers && mode !== 'module'
const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module'
const isSetupInlined = !__BROWSER__ && !!options.inline
// preambles
@@ -209,7 +214,7 @@ export function generate(
? createCodegenContext(ast, options)
: context
if (!__BROWSER__ && mode === 'module') {
genModulePreamble(ast, preambleContext, isSetupInlined)
genModulePreamble(ast, preambleContext, genScopeId, isSetupInlined)
} else {
genFunctionPreamble(ast, preambleContext)
}
@@ -226,7 +231,14 @@ export function generate(
? args.map(arg => `${arg}: any`).join(',')
: args.join(', ')
if (isSetupInlined) {
if (genScopeId) {
if (isSetupInlined) {
push(`${PURE_ANNOTATION}${WITH_ID}(`)
} else {
push(`const ${functionName} = ${PURE_ANNOTATION}${WITH_ID}(`)
}
}
if (isSetupInlined || genScopeId) {
push(`(${signature}) => {`)
} else {
push(`function ${functionName}(${signature}) {`)
@@ -291,6 +303,10 @@ export function generate(
deindent()
push(`}`)
if (genScopeId) {
push(`)`)
}
return {
ast,
code: context.code,
@@ -361,6 +377,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
function genModulePreamble(
ast: RootNode,
context: CodegenContext,
genScopeId: boolean,
inline?: boolean
) {
const {
@@ -369,12 +386,14 @@ function genModulePreamble(
optimizeImports,
runtimeModuleName,
scopeId,
mode
helper
} = context
const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module'
if (genScopeId && ast.hoists.length) {
ast.helpers.push(SET_SCOPE_ID)
if (genScopeId) {
ast.helpers.push(WITH_SCOPE_ID)
if (ast.hoists.length) {
ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID)
}
}
// generate import statements for helpers
@@ -417,6 +436,17 @@ function genModulePreamble(
newline()
}
// we technically don't need this anymore since `withCtx` already sets the
// correct scopeId, but this is necessary for backwards compat
if (genScopeId) {
push(
`const ${WITH_ID} = ${PURE_ANNOTATION}${helper(
WITH_SCOPE_ID
)}("${scopeId}")`
)
newline()
}
genHoists(ast.hoists, context)
newline()
@@ -463,7 +493,7 @@ function genHoists(hoists: (JSChildNode | null)[], context: CodegenContext) {
// push scope Id before initializing hoisted vnodes so that these vnodes
// get the proper scopeId as well.
if (genScopeId) {
push(`${helper(SET_SCOPE_ID)}("${scopeId}")`)
push(`${helper(PUSH_SCOPE_ID)}("${scopeId}")`)
newline()
}
@@ -476,7 +506,7 @@ function genHoists(hoists: (JSChildNode | null)[], context: CodegenContext) {
})
if (genScopeId) {
push(`${helper(SET_SCOPE_ID)}(null)`)
push(`${helper(POP_SCOPE_ID)}()`)
newline()
}
context.pure = false
@@ -800,12 +830,15 @@ function genFunctionExpression(
node: FunctionExpression,
context: CodegenContext
) {
const { push, indent, deindent } = context
const { push, indent, deindent, scopeId, mode } = context
const { params, returns, body, newline, isSlot } = node
// slot functions also need to push scopeId before rendering its content
const genScopeId =
!__BROWSER__ && isSlot && scopeId != null && mode !== 'function'
if (isSlot) {
// wrap slot functions with owner context
push(`_${helperNameMap[WITH_CTX]}(`)
push(genScopeId ? `${WITH_ID}(` : `_${helperNameMap[WITH_CTX]}(`)
}
push(`(`, node)
if (isArray(params)) {

View File

@@ -25,7 +25,9 @@ export const CAMELIZE = Symbol(__DEV__ ? `camelize` : ``)
export const CAPITALIZE = Symbol(__DEV__ ? `capitalize` : ``)
export const TO_HANDLER_KEY = Symbol(__DEV__ ? `toHandlerKey` : ``)
export const SET_BLOCK_TRACKING = Symbol(__DEV__ ? `setBlockTracking` : ``)
export const SET_SCOPE_ID = Symbol(__DEV__ ? `setScopeId` : ``)
export const PUSH_SCOPE_ID = Symbol(__DEV__ ? `pushScopeId` : ``)
export const POP_SCOPE_ID = Symbol(__DEV__ ? `popScopeId` : ``)
export const WITH_SCOPE_ID = Symbol(__DEV__ ? `withScopeId` : ``)
export const WITH_CTX = Symbol(__DEV__ ? `withCtx` : ``)
export const UNREF = Symbol(__DEV__ ? `unref` : ``)
export const IS_REF = Symbol(__DEV__ ? `isRef` : ``)
@@ -59,7 +61,9 @@ export const helperNameMap: any = {
[CAPITALIZE]: `capitalize`,
[TO_HANDLER_KEY]: `toHandlerKey`,
[SET_BLOCK_TRACKING]: `setBlockTracking`,
[SET_SCOPE_ID]: `setScopeId`,
[PUSH_SCOPE_ID]: `pushScopeId`,
[POP_SCOPE_ID]: `popScopeId`,
[WITH_SCOPE_ID]: `withScopeId`,
[WITH_CTX]: `withCtx`,
[UNREF]: `unref`,
[IS_REF]: `isRef`

View File

@@ -34,7 +34,7 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
slotArgs.push(createFunctionExpression([], children, false, false, loc))
}
if (context.slotted) {
if (context.scopeId && !context.slotted) {
if (!slotProps) {
slotArgs.push(`{}`)
}