From 3db29eb773b7df7e59b31d6fffd4a58a858a34d7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 8 Apr 2021 17:11:05 -0400 Subject: [PATCH] wip: support per-component compatConfig --- .../runtime-core/src/compat/compatConfig.ts | 37 +++++++++++-------- .../runtime-core/src/compat/deprecations.ts | 32 ++++++++-------- packages/runtime-core/src/componentOptions.ts | 8 +++- packages/runtime-core/src/renderer.ts | 6 +-- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/packages/runtime-core/src/compat/compatConfig.ts b/packages/runtime-core/src/compat/compatConfig.ts index d8508853d..3eae262ec 100644 --- a/packages/runtime-core/src/compat/compatConfig.ts +++ b/packages/runtime-core/src/compat/compatConfig.ts @@ -1,13 +1,11 @@ import { extend } from '@vue/shared' +import { ComponentOptions, getCurrentInstance } from '../component' import { DeprecationTypes, warnDeprecation } from './deprecations' export type CompatConfig = Partial< - Record -> - -export interface DeprecationConfigItem { - warning?: boolean // default: true - enabled?: boolean // default: true + Record +> & { + MODE?: 2 | 3 } const globalCompatConfig: CompatConfig = {} @@ -16,15 +14,24 @@ export function configureCompat(config: CompatConfig) { extend(globalCompatConfig, config) } -export function getCompatConfig( - key: DeprecationTypes -): DeprecationConfigItem | undefined { +export function getCompatConfigForKey(key: DeprecationTypes | 'MODE') { + const instance = getCurrentInstance() + const instanceConfig = + instance && (instance.type as ComponentOptions).compatConfig + if (instanceConfig && key in instanceConfig) { + return instanceConfig[key] + } return globalCompatConfig[key] } export function isCompatEnabled(key: DeprecationTypes): boolean { - const config = getCompatConfig(key) - return !config || config.enabled !== false + const mode = getCompatConfigForKey('MODE') || 2 + const val = getCompatConfigForKey(key) + if (mode === 2) { + return val !== false + } else { + return val === true || val === 'suppress-warning' + } } export function assertCompatEnabled(key: DeprecationTypes, ...args: any[]) { @@ -45,9 +52,9 @@ export function softAssertCompatEnabled(key: DeprecationTypes, ...args: any[]) { // disable features that conflict with v3 behavior if (__TEST__) { configureCompat({ - COMPONENT_ASYNC: { enabled: false }, - COMPONENT_FUNCTIONAL: { enabled: false }, - WATCH_ARRAY: { enabled: false }, - INSTANCE_ATTRS_CLASS_STYLE: { enabled: false } + COMPONENT_ASYNC: false, + COMPONENT_FUNCTIONAL: false, + WATCH_ARRAY: false, + INSTANCE_ATTRS_CLASS_STYLE: false }) } diff --git a/packages/runtime-core/src/compat/deprecations.ts b/packages/runtime-core/src/compat/deprecations.ts index 5f6e7b28f..4783b390b 100644 --- a/packages/runtime-core/src/compat/deprecations.ts +++ b/packages/runtime-core/src/compat/deprecations.ts @@ -5,7 +5,7 @@ import { isRuntimeOnly } from '../component' import { warn } from '../warning' -import { getCompatConfig } from './compatConfig' +import { getCompatConfigForKey, isCompatEnabled } from './compatConfig' export const enum DeprecationTypes { GLOBAL_MOUNT = 'GLOBAL_MOUNT', @@ -203,10 +203,10 @@ const deprecationData: Record = { `Components with inheritAttrs: false will no longer auto-inherit ` + `class/style on its root element. If your code relies on this behavior, ` + `you may see broken styling and need to adjust your CSS. Otherwise, ` + - `you can suppress this warning with:` + + `you can disable the compat behavior and suppress this warning with:` + `\n\n configureCompat({ ${ DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE - }: { warning: false }})\n`, + }: false )\n`, link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html` }, @@ -238,9 +238,7 @@ const deprecationData: Record = { `trigger on array mutation unless the "deep" option is specified. ` + `If current usage is intended, you can disable the compat behavior and ` + `suppress this warning with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.WATCH_ARRAY - }: { enabled: false }})\n`, + `\n\n configureCompat({ ${DeprecationTypes.WATCH_ARRAY}: false })\n`, link: `https://v3.vuejs.org/guide/migration/watch.html` }, @@ -273,7 +271,7 @@ const deprecationData: Record = { `you can disable the compat behavior and suppress this warning with:` + `\n\n configureCompat({ ${ DeprecationTypes.ATTR_FALSE_VALUE - }: { enabled: false }})\n`, + }: false })\n`, link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` }, @@ -288,7 +286,7 @@ const deprecationData: Record = { `you can disable the compat behavior and suppress this warning with:` + `\n\n configureCompat({ ${ DeprecationTypes.ATTR_ENUMERATED_COERSION - }: { enabled: false }})\n`, + }: false })\n`, link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` }, @@ -304,7 +302,7 @@ const deprecationData: Record = { `warning with:` + `\n\n configureCompat({ ${ DeprecationTypes.TRANSITION_GROUP_ROOT - }: { enabled: false }})\n`, + }: false })\n`, link: `https://v3.vuejs.org/guide/migration/transition-group.html` }, @@ -335,7 +333,7 @@ const deprecationData: Record = { `then disable compat for legacy async components with:` + `\n\n configureCompat({ ${ DeprecationTypes.COMPONENT_ASYNC - }: { enabled: false }})\n` + }: false })\n` ) }, link: `https://v3.vuejs.org/guide/migration/functional-components.html` @@ -354,12 +352,8 @@ export function warnDeprecation(key: DeprecationTypes, ...args: any[]) { } // check user config - const config = getCompatConfig(key) - if ( - config && - (config.warning === false || - (config.enabled === false && config.warning !== true)) - ) { + const config = getCompatConfigForKey(key) + if (config === 'suppress-warning') { return } @@ -391,4 +385,10 @@ export function warnDeprecation(key: DeprecationTypes, ...args: any[]) { typeof message === 'function' ? message(...args) : message }${link ? `\n Details: ${link}` : ``}` ) + if (!isCompatEnabled(key)) { + console.error( + `^ The above deprecation's compat behavior is disabled and will likely ` + + `lead to runtime errors.` + ) + } } diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index b92b5dcd3..4a93c697c 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -67,7 +67,11 @@ import { callWithAsyncErrorHandling } from './errorHandling' import { UnionToIntersection } from './helpers/typeUtils' import { deepMergeData } from './compat/data' import { DeprecationTypes } from './compat/deprecations' -import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig' +import { + CompatConfig, + isCompatEnabled, + softAssertCompatEnabled +} from './compat/compatConfig' /** * Interface for declaring custom options. @@ -374,6 +378,8 @@ interface LegacyOptions< Mixin extends ComponentOptionsMixin, Extends extends ComponentOptionsMixin > { + compatConfig?: CompatConfig + // allow any custom options [key: string]: any diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index ce72d6da7..a6ad23d0e 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -88,9 +88,6 @@ import { isAsyncWrapper } from './apiAsyncComponent' import { isCompatEnabled } from './compat/compatConfig' import { DeprecationTypes } from './compat/deprecations' -const isHookEventCompatEnabled = - __COMPAT__ && isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS) - export interface Renderer { render: RootRenderFunction createApp: CreateAppFunction @@ -445,6 +442,9 @@ function baseCreateRenderer( options: RendererOptions, createHydrationFns?: typeof createHydrationFunctions ): any { + const isHookEventCompatEnabled = + __COMPAT__ && isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS) + // compile-time feature flags check if (__ESM_BUNDLER__ && !__TEST__) { initFeatureFlags()