diff --git a/jest.config.js b/jest.config.js index ab41aafa3..956e0f7a4 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,7 +4,8 @@ module.exports = { __DEV__: true, __JSDOM__: true, __FEATURE_OPTIONS__: true, - __FEATURE_PRODUCTION_TIP__: false + __FEATURE_PRODUCTION_TIP__: false, + __FEATURE_SUSPENSE__: true }, coverageDirectory: 'coverage', coverageReporters: ['html', 'lcov', 'text'], diff --git a/packages/global.d.ts b/packages/global.d.ts index 60adb6451..6e0808fe0 100644 --- a/packages/global.d.ts +++ b/packages/global.d.ts @@ -5,3 +5,4 @@ declare var __JSDOM__: boolean // Feature flags declare var __FEATURE_OPTIONS__: boolean declare var __FEATURE_PRODUCTION_TIP__: boolean +declare var __FEATURE_SUSPENSE__: boolean diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index e4524d33b..60dfcbca6 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -242,9 +242,16 @@ export function setupStatefulComponent(instance: ComponentInternalInstance) { isFunction(setupResult.then) && isFunction(setupResult.catch) ) { - // async setup returned Promise. - // bail here and wait for re-entry. - instance.asyncDep = setupResult as Promise + if (__FEATURE_SUSPENSE__) { + // async setup returned Promise. + // bail here and wait for re-entry. + instance.asyncDep = setupResult as Promise + } else if (__DEV__) { + warn( + `setup() returned a Promise, but the version of Vue you are using ` + + `does not support it yet.` + ) + } return } else { handleSetupResult(instance, setupResult) diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index a582faeb1..1889aa469 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -194,15 +194,19 @@ export function createRenderer< ) break case Suspense: - processSuspense( - n1, - n2, - container, - anchor, - parentComponent, - isSVG, - optimized - ) + if (__FEATURE_SUSPENSE__) { + processSuspense( + n1, + n2, + container, + anchor, + parentComponent, + isSVG, + optimized + ) + } else if (__DEV__) { + warn(`Suspense is not enabled in the version of Vue you are using.`) + } break default: if (shapeFlag & ShapeFlags.ELEMENT) { @@ -730,10 +734,16 @@ export function createRenderer< } else { const instance = (n2.component = n1.component) as ComponentInternalInstance + // async still pending - if (instance.asyncDep && !instance.asyncResolved) { + if ( + __FEATURE_SUSPENSE__ && + instance.asyncDep && + !instance.asyncResolved + ) { return } + // a resolved async component, on successful re-entry. // pickup the mounting process and setup render effect if (!instance.update) { @@ -741,7 +751,8 @@ export function createRenderer< } else if ( shouldUpdateComponent(n1, n2, optimized) || // TODO use context suspense - (instance.provides.suspense && + (__FEATURE_SUSPENSE__ && + instance.provides.suspense && !(instance.provides.suspense as any).isResolved) ) { // normal update @@ -791,7 +802,7 @@ export function createRenderer< // setup() is async. This component relies on async logic to be resolved // before proceeding - if (instance.asyncDep) { + if (__FEATURE_SUSPENSE__ && instance.asyncDep) { // TODO use context suspense const suspense = (instance as any).provides.suspense if (!suspense) { diff --git a/rollup.config.js b/rollup.config.js index 3f530bbca..e94a5ce17 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -140,6 +140,7 @@ function createReplacePlugin(isProduction, isBunlderESMBuild, isBrowserBuild) { // support options? // the lean build drops options related code with buildOptions.lean: true __FEATURE_OPTIONS__: !packageOptions.lean, + __FEATURE_SUSPENSE__: true, // this is only used during tests __JSDOM__: false })