From 115372dd5bdd1c0c2ee2d04f16cb1b18f32aa316 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 12 Apr 2021 18:47:50 -0400 Subject: [PATCH] wip: refactor deprecations into a single file --- packages/runtime-core/src/apiWatch.ts | 2 +- .../runtime-core/src/compat/compatConfig.ts | 454 +++++++++++++++++- packages/runtime-core/src/compat/component.ts | 7 +- .../src/compat/customDirective.ts | 3 +- packages/runtime-core/src/compat/data.ts | 2 +- .../runtime-core/src/compat/deprecations.ts | 449 ----------------- packages/runtime-core/src/compat/global.ts | 3 +- .../runtime-core/src/compat/globalConfig.ts | 7 +- packages/runtime-core/src/compat/instance.ts | 2 +- .../src/compat/instanceChildren.ts | 3 +- .../src/compat/instanceEventEmitter.ts | 9 +- .../src/compat/instanceListeners.ts | 3 +- packages/runtime-core/src/compat/props.ts | 2 +- packages/runtime-core/src/compat/renderFn.ts | 3 +- packages/runtime-core/src/compat/vModel.ts | 7 +- packages/runtime-core/src/componentOptions.ts | 2 +- packages/runtime-core/src/componentProps.ts | 13 +- packages/runtime-core/src/index.ts | 4 +- packages/runtime-core/src/renderer.ts | 2 +- 19 files changed, 497 insertions(+), 480 deletions(-) delete mode 100644 packages/runtime-core/src/compat/deprecations.ts diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index e98d54788..5dc7929ee 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -33,7 +33,7 @@ import { } from './errorHandling' import { queuePostRenderEffect } from './renderer' import { warn } from './warning' -import { DeprecationTypes } from './compat/deprecations' +import { DeprecationTypes } from './compat/compatConfig' import { checkCompatEnabled, isCompatEnabled } from './compat/compatConfig' export type WatchEffect = (onInvalidate: InvalidateCbRegistrator) => void diff --git a/packages/runtime-core/src/compat/compatConfig.ts b/packages/runtime-core/src/compat/compatConfig.ts index ee2bfcacb..5f5378592 100644 --- a/packages/runtime-core/src/compat/compatConfig.ts +++ b/packages/runtime-core/src/compat/compatConfig.ts @@ -1,6 +1,454 @@ -import { extend } from '@vue/shared' -import { ComponentInternalInstance, ComponentOptions } from '../component' -import { DeprecationTypes, warnDeprecation } from './deprecations' +import { extend, hasOwn, isArray } from '@vue/shared' +import { + ComponentInternalInstance, + ComponentOptions, + formatComponentName, + getComponentName, + getCurrentInstance, + isRuntimeOnly +} from '../component' +import { warn } from '../warning' + +export const enum DeprecationTypes { + GLOBAL_MOUNT = 'GLOBAL_MOUNT', + GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER', + GLOBAL_EXTEND = 'GLOBAL_EXTEND', + GLOBAL_PROTOTYPE = 'GLOBAL_PROTOTYPE', + GLOBAL_SET = 'GLOBAL_SET', + GLOBAL_DELETE = 'GLOBAL_DELETE', + GLOBAL_OBSERVABLE = 'GLOBAL_OBSERVABLE', + GLOBAL_UTIL = 'GLOBAL_UTIL', + + CONFIG_SILENT = 'CONFIG_SILENT', + CONFIG_DEVTOOLS = 'CONFIG_DEVTOOLS', + CONFIG_KEY_CODES = 'CONFIG_KEY_CODES', + CONFIG_PRODUCTION_TIP = 'CONFIG_PRODUCTION_TIP', + CONFIG_IGNORED_ELEMENTS = 'CONFIG_IGNORED_ELEMENTS', + + INSTANCE_SET = 'INSTANCE_SET', + INSTANCE_DELETE = 'INSTANCE_DELETE', + INSTANCE_DESTROY = 'INSTANCE_DESTROY', + INSTANCE_EVENT_EMITTER = 'INSTANCE_EVENT_EMITTER', + INSTANCE_EVENT_HOOKS = 'INSTANCE_EVENT_HOOKS', + INSTANCE_CHILDREN = 'INSTANCE_CHILDREN', + INSTANCE_LISTENERS = 'INSTANCE_LISTENERS', + INSTANCE_SCOPED_SLOTS = 'INSTANCE_SCOPED_SLOTS', + INSTANCE_ATTRS_CLASS_STYLE = 'INSTANCE_ATTRS_CLASS_STYLE', + + OPTIONS_DATA_FN = 'OPTIONS_DATA_FN', + OPTIONS_DATA_MERGE = 'OPTIONS_DATA_MERGE', + OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY', + OPTIONS_DESTROYED = 'OPTIONS_DESTROYED', + + WATCH_ARRAY = 'WATCH_ARRAY', + PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS', + + V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER', + CUSTOM_DIR = 'CUSTOM_DIR', + + ATTR_FALSE_VALUE = 'ATTR_FALSE_VALUE', + ATTR_ENUMERATED_COERSION = 'ATTR_ENUMERATED_COERSION', + + TRANSITION_CLASSES = 'TRANSITION_CLASSES', + TRANSITION_GROUP_ROOT = 'TRANSITION_GROUP_ROOT', + + COMPONENT_ASYNC = 'COMPONENT_ASYNC', + COMPONENT_FUNCTIONAL = 'COMPONENT_FUNCTIONAL', + COMPONENT_V_MODEL = 'COMPONENT_V_MODEL', + + RENDER_FUNCTION = 'RENDER_FUNCTION' +} + +type DeprecationData = { + message: string | ((...args: any[]) => string) + link?: string +} + +const deprecationData: Record = { + [DeprecationTypes.GLOBAL_MOUNT]: { + message: + `The global app bootstrapping API has changed: vm.$mount() and the "el" ` + + `option have been removed. Use createApp(RootComponent).mount() instead.`, + link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance` + }, + + [DeprecationTypes.GLOBAL_MOUNT_CONTAINER]: { + message: + `Vue detected directives on the mount container. ` + + `In Vue 3, the container is no longer considered part of the template ` + + `and will not be processed/replaced.`, + link: `https://v3.vuejs.org/guide/migration/mount-changes.html` + }, + + [DeprecationTypes.GLOBAL_EXTEND]: { + message: + `Vue.extend() has been removed in Vue 3. ` + + `Use defineComponent() instead.`, + link: `https://v3.vuejs.org/api/global-api.html#definecomponent` + }, + + [DeprecationTypes.GLOBAL_PROTOTYPE]: { + message: + `Vue.prototype is no longer available in Vue 3. ` + + `Use config.globalProperties instead.`, + link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties` + }, + + [DeprecationTypes.GLOBAL_SET]: { + message: + `Vue.set() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + + [DeprecationTypes.GLOBAL_DELETE]: { + message: + `Vue.delete() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + + [DeprecationTypes.GLOBAL_OBSERVABLE]: { + message: + `Vue.observable() has been removed. ` + + `Use \`import { reactive } from "vue"\` from Composition API instead.`, + link: `https://v3.vuejs.org/api/basic-reactivity.html` + }, + + [DeprecationTypes.GLOBAL_UTIL]: { + message: + `Vue.util has been removed. Please refactor to avoid its usage ` + + `since it was an internal API even in Vue 2.` + }, + + [DeprecationTypes.CONFIG_SILENT]: { + message: + `config.silent has been removed because it is not good practice to ` + + `intentionally suppress warnings. You can use your browser console's ` + + `filter features to focus on relevant messages.` + }, + + [DeprecationTypes.CONFIG_DEVTOOLS]: { + message: + `config.devtools has been removed. To enable devtools for ` + + `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`, + link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags` + }, + + [DeprecationTypes.CONFIG_KEY_CODES]: { + message: + `config.keyCodes has been removed. ` + + `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`, + link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` + }, + + [DeprecationTypes.CONFIG_PRODUCTION_TIP]: { + message: `config.productionTip has been removed.`, + link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed` + }, + + [DeprecationTypes.CONFIG_IGNORED_ELEMENTS]: { + message: () => { + let msg = `config.ignoredElements has been removed.` + if (isRuntimeOnly()) { + msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.` + } else { + msg += ` Use config.isCustomElement instead.` + } + return msg + }, + link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement` + }, + + [DeprecationTypes.INSTANCE_SET]: { + message: + `vm.$set() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + + [DeprecationTypes.INSTANCE_DELETE]: { + message: + `vm.$delete() has been removed as it is no longer needed in Vue 3. ` + + `Simply use native JavaScript mutations.` + }, + + [DeprecationTypes.INSTANCE_DESTROY]: { + message: `vm.$destroy() has been removed. Use app.unmount() instead.`, + link: `https://v3.vuejs.org/api/application-api.html#unmount` + }, + + [DeprecationTypes.INSTANCE_EVENT_EMITTER]: { + message: + `vm.$on/$once/$off() have been removed. ` + + `Use an external event emitter library instead.`, + link: `https://v3.vuejs.org/guide/migration/events-api.html` + }, + + [DeprecationTypes.INSTANCE_EVENT_HOOKS]: { + message: event => + `"${event}" lifecycle events are no longer supported. From templates, ` + + `use the "vnode" prefix instead of "hook:". For example, @${event} ` + + `should be changed to @vnode-${event.slice(5)}. ` + + `From JavaScript, use Composition API to dynamically register lifecycle ` + + `hooks.`, + link: `https://v3.vuejs.org/guide/migration/vnode-lifecycle-events.html` + }, + + [DeprecationTypes.INSTANCE_CHILDREN]: { + message: + `vm.$children has been removed. Consider refactoring your logic ` + + `to avoid relying on direct access to child components.`, + link: `https://v3.vuejs.org/guide/migration/children.html` + }, + + [DeprecationTypes.INSTANCE_LISTENERS]: { + message: + `vm.$listeners has been removed. Parent v-on listeners are now ` + + `included in vm.$attrs and it is no longer necessary to separately use ` + + `v-on="$listeners" if you are already using v-bind="$attrs".`, + link: `https://v3.vuejs.org/guide/migration/listeners-removed.html` + }, + + [DeprecationTypes.INSTANCE_SCOPED_SLOTS]: { + message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`, + link: `https://v3.vuejs.org/guide/migration/slots-unification.html` + }, + + [DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE]: { + message: + `vm.$attrs now includes class and style bindings passed from parent. ` + + `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 disable the compat behavior and suppress this warning with:` + + `\n\n configureCompat({ ${ + DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE + }: false )\n`, + link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html` + }, + + [DeprecationTypes.OPTIONS_DATA_FN]: { + message: + `The "data" option can no longer be a plain object. ` + + `Always use a function.`, + link: `https://v3.vuejs.org/guide/migration/data-option.html` + }, + + [DeprecationTypes.OPTIONS_DATA_MERGE]: { + message: (key: string) => + `Detected conflicting key "${key}" when merging data option values. ` + + `In Vue 3, data keys are merged shallowly and will override one another.`, + link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change` + }, + + [DeprecationTypes.OPTIONS_BEFORE_DESTROY]: { + message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.` + }, + + [DeprecationTypes.OPTIONS_DESTROYED]: { + message: `\`destroyed\` has been renamed to \`unmounted\`.` + }, + + [DeprecationTypes.WATCH_ARRAY]: { + message: + `"watch" option or vm.$watch on an array value will no longer ` + + `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}: false })\n`, + link: `https://v3.vuejs.org/guide/migration/watch.html` + }, + + [DeprecationTypes.PROPS_DEFAULT_THIS]: { + message: (key: string) => + `props default value function no longer has access to "this". ` + + `(found in prop "${key}")`, + link: `https://v3.vuejs.org/guide/migration/props-default-this.html` + }, + + [DeprecationTypes.CUSTOM_DIR]: { + message: (legacyHook: string, newHook: string) => + `Custom directive hook "${legacyHook}" has been removed. ` + + `Use "${newHook}" instead.`, + link: `https://v3.vuejs.org/guide/migration/custom-directives.html` + }, + + [DeprecationTypes.V_ON_KEYCODE_MODIFIER]: { + message: + `Using keyCode as v-on modifier is no longer supported. ` + + `Use kebab-case key name modifiers instead.`, + link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` + }, + + [DeprecationTypes.ATTR_FALSE_VALUE]: { + message: (name: string) => + `Attribute "${name}" with v-bind value \`false\` will render ` + + `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` + + `use \`null\` or \`undefined\` instead. If the usage is intended, ` + + `you can disable the compat behavior and suppress this warning with:` + + `\n\n configureCompat({ ${ + DeprecationTypes.ATTR_FALSE_VALUE + }: false })\n`, + link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` + }, + + [DeprecationTypes.ATTR_ENUMERATED_COERSION]: { + message: (name: string, value: any, coerced: string) => + `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` + + `${ + value === null ? `be removed` : `render the value as-is` + } instead of coercing the value to "${coerced}" in Vue 3. ` + + `Always use explicit "true" or "false" values for enumerated attributes. ` + + `If the usage is intended, ` + + `you can disable the compat behavior and suppress this warning with:` + + `\n\n configureCompat({ ${ + DeprecationTypes.ATTR_ENUMERATED_COERSION + }: false })\n`, + link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` + }, + + [DeprecationTypes.TRANSITION_CLASSES]: { + message: `` // this feature cannot be runtime-detected + }, + + [DeprecationTypes.TRANSITION_GROUP_ROOT]: { + message: + ` no longer renders a root element by ` + + `default if no "tag" prop is specified. If you do not rely on the span ` + + `for styling, you can disable the compat behavior and suppress this ` + + `warning with:` + + `\n\n configureCompat({ ${ + DeprecationTypes.TRANSITION_GROUP_ROOT + }: false })\n`, + link: `https://v3.vuejs.org/guide/migration/transition-group.html` + }, + + [DeprecationTypes.COMPONENT_ASYNC]: { + message: (comp: any) => { + const name = getComponentName(comp) + return ( + `Async component${ + name ? ` <${name}>` : `s` + } should be explicitly created via \`defineAsyncComponent()\` ` + + `in Vue 3. Plain functions will be treated as functional components in ` + + `non-compat build. If you have already migrated all async component ` + + `usage and intend to use plain functions for functional components, ` + + `you can disable the compat behavior and suppress this ` + + `warning with:` + + `\n\n configureCompat({ ${ + DeprecationTypes.COMPONENT_ASYNC + }: false })\n` + ) + }, + link: `https://v3.vuejs.org/guide/migration/async-components.html` + }, + + [DeprecationTypes.COMPONENT_FUNCTIONAL]: { + message: (comp: any) => { + const name = getComponentName(comp) + return ( + `Functional component${ + name ? ` <${name}>` : `s` + } should be defined as a plain function in Vue 3. The "functional" ` + + `option has been removed. NOTE: Before migrating to use plain ` + + `functions for functional components, first make sure that all async ` + + `components usage have been migrated and its compat behavior has ` + + `been disabled.` + ) + }, + link: `https://v3.vuejs.org/guide/migration/functional-components.html` + }, + + [DeprecationTypes.COMPONENT_V_MODEL]: { + message: (comp: ComponentOptions) => { + const configMsg = + `opt-in to ` + + `Vue 3 behavior on a per-component basis with \`compatConfig: { ${ + DeprecationTypes.COMPONENT_V_MODEL + }: false }\`.` + if ( + comp.props && isArray(comp.props) + ? comp.props.includes('modelValue') + : hasOwn(comp.props, 'modelValue') + ) { + return ( + `Component delcares "modelValue" prop, which is Vue 3 usage, but ` + + `is running under Vue 2 compat v-model behavior. You can ${configMsg}` + ) + } + return ( + `v-model usage on component has changed in Vue 3. Component that expects ` + + `to work with v-model should now use the "modelValue" prop and emit the ` + + `"update:modelValue" event. You can update the usage and then ${configMsg}` + ) + }, + link: `https://v3.vuejs.org/guide/migration/v-model.html` + }, + + [DeprecationTypes.RENDER_FUNCTION]: { + message: + `Vue 3's render function API has changed. ` + + `You can opt-in to the new API with:` + + `\n\n configureCompat({ ${ + DeprecationTypes.RENDER_FUNCTION + }: false })\n` + + `\n (This can also be done per-component via the "compatConfig" option.)`, + link: `https://v3.vuejs.org/guide/migration/render-function-api.html` + } +} + +const instanceWarned: Record = Object.create(null) +const warnCount: Record = Object.create(null) + +export function warnDeprecation( + key: DeprecationTypes, + instance: ComponentInternalInstance | null, + ...args: any[] +) { + if (!__DEV__) { + return + } + + instance = instance || getCurrentInstance() + + // check user config + const config = getCompatConfigForKey(key, instance) + if (config === 'suppress-warning') { + return + } + + const dupKey = key + args.join('') + const compName = instance && formatComponentName(instance, instance.type) + + // skip if the same warning is emitted for the same component type + if (compName !== `Anonymous`) { + const componentDupKey = dupKey + compName + if (componentDupKey in instanceWarned) { + return + } + instanceWarned[componentDupKey] = true + } + + // same warning, but different component. skip the long message and just + // log the key and count. + if (dupKey in warnCount) { + warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`) + return + } + + warnCount[dupKey] = 0 + + const { message, link } = deprecationData[key] + warn( + `(deprecation ${key}) ${ + typeof message === 'function' ? message(...args) : message + }${link ? `\n Details: ${link}` : ``}` + ) + if (!isCompatEnabled(key, instance)) { + console.error( + `^ The above deprecation's compat behavior is disabled and will likely ` + + `lead to runtime errors.` + ) + } +} export type CompatConfig = Partial< Record diff --git a/packages/runtime-core/src/compat/component.ts b/packages/runtime-core/src/compat/component.ts index d77477891..0cae7ad38 100644 --- a/packages/runtime-core/src/compat/component.ts +++ b/packages/runtime-core/src/compat/component.ts @@ -10,8 +10,11 @@ import { import { resolveInjections } from '../componentOptions' import { InternalSlots } from '../componentSlots' import { isVNode } from '../vnode' -import { checkCompatEnabled, softAssertCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' +import { + checkCompatEnabled, + softAssertCompatEnabled, + DeprecationTypes +} from './compatConfig' import { getCompatListeners } from './instanceListeners' import { compatH } from './renderFn' diff --git a/packages/runtime-core/src/compat/customDirective.ts b/packages/runtime-core/src/compat/customDirective.ts index f6303c4e6..dc854dbca 100644 --- a/packages/runtime-core/src/compat/customDirective.ts +++ b/packages/runtime-core/src/compat/customDirective.ts @@ -1,8 +1,7 @@ import { isArray } from '@vue/shared' import { ComponentInternalInstance } from '../component' import { ObjectDirective, DirectiveHook } from '../directives' -import { softAssertCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' +import { softAssertCompatEnabled, DeprecationTypes } from './compatConfig' export interface LegacyDirective { bind?: DirectiveHook diff --git a/packages/runtime-core/src/compat/data.ts b/packages/runtime-core/src/compat/data.ts index c296b460a..87663dbd0 100644 --- a/packages/runtime-core/src/compat/data.ts +++ b/packages/runtime-core/src/compat/data.ts @@ -1,6 +1,6 @@ import { isPlainObject } from '@vue/shared' import { ComponentInternalInstance } from '../component' -import { DeprecationTypes, warnDeprecation } from './deprecations' +import { DeprecationTypes, warnDeprecation } from './compatConfig' export function deepMergeData( to: any, diff --git a/packages/runtime-core/src/compat/deprecations.ts b/packages/runtime-core/src/compat/deprecations.ts deleted file mode 100644 index f33f360d8..000000000 --- a/packages/runtime-core/src/compat/deprecations.ts +++ /dev/null @@ -1,449 +0,0 @@ -import { hasOwn, isArray } from '@vue/shared' -import { - ComponentInternalInstance, - ComponentOptions, - formatComponentName, - getComponentName, - getCurrentInstance, - isRuntimeOnly -} from '../component' -import { warn } from '../warning' -import { getCompatConfigForKey, isCompatEnabled } from './compatConfig' - -export const enum DeprecationTypes { - GLOBAL_MOUNT = 'GLOBAL_MOUNT', - GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER', - GLOBAL_EXTEND = 'GLOBAL_EXTEND', - GLOBAL_PROTOTYPE = 'GLOBAL_PROTOTYPE', - GLOBAL_SET = 'GLOBAL_SET', - GLOBAL_DELETE = 'GLOBAL_DELETE', - GLOBAL_OBSERVABLE = 'GLOBAL_OBSERVABLE', - GLOBAL_UTIL = 'GLOBAL_UTIL', - - CONFIG_SILENT = 'CONFIG_SILENT', - CONFIG_DEVTOOLS = 'CONFIG_DEVTOOLS', - CONFIG_KEY_CODES = 'CONFIG_KEY_CODES', - CONFIG_PRODUCTION_TIP = 'CONFIG_PRODUCTION_TIP', - CONFIG_IGNORED_ELEMENTS = 'CONFIG_IGNORED_ELEMENTS', - - INSTANCE_SET = 'INSTANCE_SET', - INSTANCE_DELETE = 'INSTANCE_DELETE', - INSTANCE_DESTROY = 'INSTANCE_DESTROY', - INSTANCE_EVENT_EMITTER = 'INSTANCE_EVENT_EMITTER', - INSTANCE_EVENT_HOOKS = 'INSTANCE_EVENT_HOOKS', - INSTANCE_CHILDREN = 'INSTANCE_CHILDREN', - INSTANCE_LISTENERS = 'INSTANCE_LISTENERS', - INSTANCE_SCOPED_SLOTS = 'INSTANCE_SCOPED_SLOTS', - INSTANCE_ATTRS_CLASS_STYLE = 'INSTANCE_ATTRS_CLASS_STYLE', - - OPTIONS_DATA_FN = 'OPTIONS_DATA_FN', - OPTIONS_DATA_MERGE = 'OPTIONS_DATA_MERGE', - OPTIONS_BEFORE_DESTROY = 'OPTIONS_BEFORE_DESTROY', - OPTIONS_DESTROYED = 'OPTIONS_DESTROYED', - - WATCH_ARRAY = 'WATCH_ARRAY', - PROPS_DEFAULT_THIS = 'PROPS_DEFAULT_THIS', - - V_ON_KEYCODE_MODIFIER = 'V_ON_KEYCODE_MODIFIER', - CUSTOM_DIR = 'CUSTOM_DIR', - - ATTR_FALSE_VALUE = 'ATTR_FALSE_VALUE', - ATTR_ENUMERATED_COERSION = 'ATTR_ENUMERATED_COERSION', - - TRANSITION_CLASSES = 'TRANSITION_CLASSES', - TRANSITION_GROUP_ROOT = 'TRANSITION_GROUP_ROOT', - - COMPONENT_ASYNC = 'COMPONENT_ASYNC', - COMPONENT_FUNCTIONAL = 'COMPONENT_FUNCTIONAL', - COMPONENT_V_MODEL = 'COMPONENT_V_MODEL', - - RENDER_FUNCTION = 'RENDER_FUNCTION' -} - -type DeprecationData = { - message: string | ((...args: any[]) => string) - link?: string -} - -const deprecationData: Record = { - [DeprecationTypes.GLOBAL_MOUNT]: { - message: - `The global app bootstrapping API has changed: vm.$mount() and the "el" ` + - `option have been removed. Use createApp(RootComponent).mount() instead.`, - link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance` - }, - - [DeprecationTypes.GLOBAL_MOUNT_CONTAINER]: { - message: - `Vue detected directives on the mount container. ` + - `In Vue 3, the container is no longer considered part of the template ` + - `and will not be processed/replaced.`, - link: `https://v3.vuejs.org/guide/migration/mount-changes.html` - }, - - [DeprecationTypes.GLOBAL_EXTEND]: { - message: - `Vue.extend() has been removed in Vue 3. ` + - `Use defineComponent() instead.`, - link: `https://v3.vuejs.org/api/global-api.html#definecomponent` - }, - - [DeprecationTypes.GLOBAL_PROTOTYPE]: { - message: - `Vue.prototype is no longer available in Vue 3. ` + - `Use config.globalProperties instead.`, - link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties` - }, - - [DeprecationTypes.GLOBAL_SET]: { - message: - `Vue.set() has been removed as it is no longer needed in Vue 3. ` + - `Simply use native JavaScript mutations.` - }, - - [DeprecationTypes.GLOBAL_DELETE]: { - message: - `Vue.delete() has been removed as it is no longer needed in Vue 3. ` + - `Simply use native JavaScript mutations.` - }, - - [DeprecationTypes.GLOBAL_OBSERVABLE]: { - message: - `Vue.observable() has been removed. ` + - `Use \`import { reactive } from "vue"\` from Composition API instead.`, - link: `https://v3.vuejs.org/api/basic-reactivity.html` - }, - - [DeprecationTypes.GLOBAL_UTIL]: { - message: - `Vue.util has been removed. Please refactor to avoid its usage ` + - `since it was an internal API even in Vue 2.` - }, - - [DeprecationTypes.CONFIG_SILENT]: { - message: - `config.silent has been removed because it is not good practice to ` + - `intentionally suppress warnings. You can use your browser console's ` + - `filter features to focus on relevant messages.` - }, - - [DeprecationTypes.CONFIG_DEVTOOLS]: { - message: - `config.devtools has been removed. To enable devtools for ` + - `production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`, - link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags` - }, - - [DeprecationTypes.CONFIG_KEY_CODES]: { - message: - `config.keyCodes has been removed. ` + - `In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`, - link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` - }, - - [DeprecationTypes.CONFIG_PRODUCTION_TIP]: { - message: `config.productionTip has been removed.`, - link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed` - }, - - [DeprecationTypes.CONFIG_IGNORED_ELEMENTS]: { - message: () => { - let msg = `config.ignoredElements has been removed.` - if (isRuntimeOnly()) { - msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.` - } else { - msg += ` Use config.isCustomElement instead.` - } - return msg - }, - link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement` - }, - - [DeprecationTypes.INSTANCE_SET]: { - message: - `vm.$set() has been removed as it is no longer needed in Vue 3. ` + - `Simply use native JavaScript mutations.` - }, - - [DeprecationTypes.INSTANCE_DELETE]: { - message: - `vm.$delete() has been removed as it is no longer needed in Vue 3. ` + - `Simply use native JavaScript mutations.` - }, - - [DeprecationTypes.INSTANCE_DESTROY]: { - message: `vm.$destroy() has been removed. Use app.unmount() instead.`, - link: `https://v3.vuejs.org/api/application-api.html#unmount` - }, - - [DeprecationTypes.INSTANCE_EVENT_EMITTER]: { - message: - `vm.$on/$once/$off() have been removed. ` + - `Use an external event emitter library instead.`, - link: `https://v3.vuejs.org/guide/migration/events-api.html` - }, - - [DeprecationTypes.INSTANCE_EVENT_HOOKS]: { - message: - `"hook:x" lifecycle events are no longer supported. ` + - `Use Composition API to dynamically register lifecycle hooks.`, - link: `https://v3.vuejs.org/api/composition-api.html#lifecycle-hooks` - }, - - [DeprecationTypes.INSTANCE_CHILDREN]: { - message: - `vm.$children has been removed. Consider refactoring your logic ` + - `to avoid relying on direct access to child components.`, - link: `https://v3.vuejs.org/guide/migration/children.html` - }, - - [DeprecationTypes.INSTANCE_LISTENERS]: { - message: - `vm.$listeners has been removed. Parent v-on listeners are now ` + - `included in vm.$attrs and it is no longer necessary to separately use ` + - `v-on="$listeners" if you are already using v-bind="$attrs".`, - link: `https://v3.vuejs.org/guide/migration/listeners-removed.html` - }, - - [DeprecationTypes.INSTANCE_SCOPED_SLOTS]: { - message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`, - link: `https://v3.vuejs.org/guide/migration/slots-unification.html` - }, - - [DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE]: { - message: - `vm.$attrs now includes class and style bindings passed from parent. ` + - `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 disable the compat behavior and suppress this warning with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.INSTANCE_ATTRS_CLASS_STYLE - }: false )\n`, - link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html` - }, - - [DeprecationTypes.OPTIONS_DATA_FN]: { - message: - `The "data" option can no longer be a plain object. ` + - `Always use a function.`, - link: `https://v3.vuejs.org/guide/migration/data-option.html` - }, - - [DeprecationTypes.OPTIONS_DATA_MERGE]: { - message: (key: string) => - `Detected conflicting key "${key}" when merging data option values. ` + - `In Vue 3, data keys are merged shallowly and will override one another.`, - link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change` - }, - - [DeprecationTypes.OPTIONS_BEFORE_DESTROY]: { - message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.` - }, - - [DeprecationTypes.OPTIONS_DESTROYED]: { - message: `\`destroyed\` has been renamed to \`unmounted\`.` - }, - - [DeprecationTypes.WATCH_ARRAY]: { - message: - `"watch" option or vm.$watch on an array value will no longer ` + - `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}: false })\n`, - link: `https://v3.vuejs.org/guide/migration/watch.html` - }, - - [DeprecationTypes.PROPS_DEFAULT_THIS]: { - message: (key: string) => - `props default value function no longer has access to "this". ` + - `(found in prop "${key}")`, - link: `https://v3.vuejs.org/guide/migration/props-default-this.html` - }, - - [DeprecationTypes.CUSTOM_DIR]: { - message: (legacyHook: string, newHook: string) => - `Custom directive hook "${legacyHook}" has been removed. ` + - `Use "${newHook}" instead.`, - link: `https://v3.vuejs.org/guide/migration/custom-directives.html` - }, - - [DeprecationTypes.V_ON_KEYCODE_MODIFIER]: { - message: - `Using keyCode as v-on modifier is no longer supported. ` + - `Use kebab-case key name modifiers instead.`, - link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html` - }, - - [DeprecationTypes.ATTR_FALSE_VALUE]: { - message: (name: string) => - `Attribute "${name}" with v-bind value \`false\` will render ` + - `${name}="false" instead of removing it in Vue 3. To remove the attribute, ` + - `use \`null\` or \`undefined\` instead. If the usage is intended, ` + - `you can disable the compat behavior and suppress this warning with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.ATTR_FALSE_VALUE - }: false })\n`, - link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` - }, - - [DeprecationTypes.ATTR_ENUMERATED_COERSION]: { - message: (name: string, value: any, coerced: string) => - `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` + - `${ - value === null ? `be removed` : `render the value as-is` - } instead of coercing the value to "${coerced}" in Vue 3. ` + - `Always use explicit "true" or "false" values for enumerated attributes. ` + - `If the usage is intended, ` + - `you can disable the compat behavior and suppress this warning with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.ATTR_ENUMERATED_COERSION - }: false })\n`, - link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html` - }, - - [DeprecationTypes.TRANSITION_CLASSES]: { - message: `` // this feature cannot be runtime-detected - }, - - [DeprecationTypes.TRANSITION_GROUP_ROOT]: { - message: - ` no longer renders a root element by ` + - `default if no "tag" prop is specified. If you do not rely on the span ` + - `for styling, you can disable the compat behavior and suppress this ` + - `warning with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.TRANSITION_GROUP_ROOT - }: false })\n`, - link: `https://v3.vuejs.org/guide/migration/transition-group.html` - }, - - [DeprecationTypes.COMPONENT_ASYNC]: { - message: (comp: any) => { - const name = getComponentName(comp) - return ( - `Async component${ - name ? ` <${name}>` : `s` - } should be explicitly created via \`defineAsyncComponent()\` ` + - `in Vue 3. Plain functions will be treated as functional components in ` + - `non-compat build. If you have already migrated all async component ` + - `usage and intend to use plain functions for functional components, ` + - `you can disable the compat behavior and suppress this ` + - `warning with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.COMPONENT_ASYNC - }: false })\n` - ) - }, - link: `https://v3.vuejs.org/guide/migration/async-components.html` - }, - - [DeprecationTypes.COMPONENT_FUNCTIONAL]: { - message: (comp: any) => { - const name = getComponentName(comp) - return ( - `Functional component${ - name ? ` <${name}>` : `s` - } should be defined as a plain function in Vue 3. The "functional" ` + - `option has been removed. NOTE: Before migrating to use plain ` + - `functions for functional components, first make sure that all async ` + - `components usage have been migrated and its compat behavior has ` + - `been disabled.` - ) - }, - link: `https://v3.vuejs.org/guide/migration/functional-components.html` - }, - - [DeprecationTypes.COMPONENT_V_MODEL]: { - message: (comp: ComponentOptions) => { - const configMsg = - `opt-in to ` + - `Vue 3 behavior on a per-component basis with \`compatConfig: { ${ - DeprecationTypes.COMPONENT_V_MODEL - }: false }\`.` - if ( - comp.props && isArray(comp.props) - ? comp.props.includes('modelValue') - : hasOwn(comp.props, 'modelValue') - ) { - return ( - `Component delcares "modelValue" prop, which is Vue 3 usage, but ` + - `is running under Vue 2 compat v-model behavior. You can ${configMsg}` - ) - } - return ( - `v-model usage on component has changed in Vue 3. Component that expects ` + - `to work with v-model should now use the "modelValue" prop and emit the ` + - `"update:modelValue" event. You can update the usage and then ${configMsg}` - ) - }, - link: `https://v3.vuejs.org/guide/migration/v-model.html` - }, - - [DeprecationTypes.RENDER_FUNCTION]: { - message: - `Vue 3's render function API has changed. ` + - `You can opt-in to the new API with:` + - `\n\n configureCompat({ ${ - DeprecationTypes.RENDER_FUNCTION - }: false })\n` + - `\n (This can also be done per-component via the "compatConfig" option.)`, - link: `https://v3.vuejs.org/guide/migration/render-function-api.html` - } -} - -const instanceWarned: Record = Object.create(null) -const warnCount: Record = Object.create(null) - -export function warnDeprecation( - key: DeprecationTypes, - instance: ComponentInternalInstance | null, - ...args: any[] -) { - if (!__DEV__) { - return - } - - instance = instance || getCurrentInstance() - - // check user config - const config = getCompatConfigForKey(key, instance) - if (config === 'suppress-warning') { - return - } - - const dupKey = key + args.join('') - const compName = instance && formatComponentName(instance, instance.type) - - // skip if the same warning is emitted for the same component type - if (compName !== `Anonymous`) { - const componentDupKey = dupKey + compName - if (componentDupKey in instanceWarned) { - return - } - instanceWarned[componentDupKey] = true - } - - // same warning, but different component. skip the long message and just - // log the key and count. - if (dupKey in warnCount) { - warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`) - return - } - - warnCount[dupKey] = 0 - - const { message, link } = deprecationData[key] - warn( - `(deprecation ${key}) ${ - typeof message === 'function' ? message(...args) : message - }${link ? `\n Details: ${link}` : ``}` - ) - if (!isCompatEnabled(key, instance)) { - console.error( - `^ The above deprecation's compat behavior is disabled and will likely ` + - `lead to runtime errors.` - ) - } -} diff --git a/packages/runtime-core/src/compat/global.ts b/packages/runtime-core/src/compat/global.ts index 13cb05c80..de89c0a90 100644 --- a/packages/runtime-core/src/compat/global.ts +++ b/packages/runtime-core/src/compat/global.ts @@ -39,11 +39,12 @@ import { ComponentPublicInstance } from '../componentPublicInstance' import { devtoolsInitApp } from '../devtools' import { Directive } from '../directives' import { nextTick } from '../scheduler' -import { warnDeprecation, DeprecationTypes } from './deprecations' import { version } from '..' import { LegacyConfig } from './globalConfig' import { LegacyDirective } from './customDirective' import { + warnDeprecation, + DeprecationTypes, assertCompatEnabled, configureCompat, isCompatEnabled, diff --git a/packages/runtime-core/src/compat/globalConfig.ts b/packages/runtime-core/src/compat/globalConfig.ts index fab0196fa..bed3fc39e 100644 --- a/packages/runtime-core/src/compat/globalConfig.ts +++ b/packages/runtime-core/src/compat/globalConfig.ts @@ -1,9 +1,12 @@ import { extend, isArray, isString } from '@vue/shared' import { AppConfig } from '../apiCreateApp' import { isRuntimeOnly } from '../component' -import { isCompatEnabled } from './compatConfig' import { deepMergeData } from './data' -import { DeprecationTypes, warnDeprecation } from './deprecations' +import { + DeprecationTypes, + warnDeprecation, + isCompatEnabled +} from './compatConfig' import { isCopyingConfig } from './global' // legacy config warnings diff --git a/packages/runtime-core/src/compat/instance.ts b/packages/runtime-core/src/compat/instance.ts index 2f9c254df..60144fa6f 100644 --- a/packages/runtime-core/src/compat/instance.ts +++ b/packages/runtime-core/src/compat/instance.ts @@ -2,11 +2,11 @@ import { extend, NOOP } from '@vue/shared' import { PublicPropertiesMap } from '../componentPublicInstance' import { getCompatChildren } from './instanceChildren' import { + DeprecationTypes, assertCompatEnabled, checkCompatEnabled, isCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' import { off, on, once } from './instanceEventEmitter' import { getCompatListeners } from './instanceListeners' import { shallowReadonly } from '@vue/reactivity' diff --git a/packages/runtime-core/src/compat/instanceChildren.ts b/packages/runtime-core/src/compat/instanceChildren.ts index 09bb4a9fe..349b5a3fc 100644 --- a/packages/runtime-core/src/compat/instanceChildren.ts +++ b/packages/runtime-core/src/compat/instanceChildren.ts @@ -2,8 +2,7 @@ import { ShapeFlags } from '@vue/shared/src' import { ComponentInternalInstance } from '../component' import { ComponentPublicInstance } from '../componentPublicInstance' import { VNode } from '../vnode' -import { assertCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' +import { assertCompatEnabled, DeprecationTypes } from './compatConfig' export function getCompatChildren( instance: ComponentInternalInstance diff --git a/packages/runtime-core/src/compat/instanceEventEmitter.ts b/packages/runtime-core/src/compat/instanceEventEmitter.ts index 0e1307bad..64237e916 100644 --- a/packages/runtime-core/src/compat/instanceEventEmitter.ts +++ b/packages/runtime-core/src/compat/instanceEventEmitter.ts @@ -1,8 +1,7 @@ import { isArray } from '@vue/shared' import { ComponentInternalInstance } from '../component' import { callWithAsyncErrorHandling, ErrorCodes } from '../errorHandling' -import { assertCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' +import { assertCompatEnabled, DeprecationTypes } from './compatConfig' interface EventRegistry { [event: string]: Function[] | undefined @@ -32,7 +31,11 @@ export function on( event.forEach(e => on(instance, e, fn)) } else { if (event.startsWith('hook:')) { - assertCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance) + assertCompatEnabled( + DeprecationTypes.INSTANCE_EVENT_HOOKS, + instance, + event + ) } else { assertCompatEnabled(DeprecationTypes.INSTANCE_EVENT_EMITTER, instance) } diff --git a/packages/runtime-core/src/compat/instanceListeners.ts b/packages/runtime-core/src/compat/instanceListeners.ts index 263d19611..973d440b1 100644 --- a/packages/runtime-core/src/compat/instanceListeners.ts +++ b/packages/runtime-core/src/compat/instanceListeners.ts @@ -1,7 +1,6 @@ import { isOn } from '@vue/shared' import { ComponentInternalInstance } from '../component' -import { assertCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' +import { assertCompatEnabled, DeprecationTypes } from './compatConfig' export function getCompatListeners(instance: ComponentInternalInstance) { assertCompatEnabled(DeprecationTypes.INSTANCE_LISTENERS, instance) diff --git a/packages/runtime-core/src/compat/props.ts b/packages/runtime-core/src/compat/props.ts index 48d75fa52..51871562d 100644 --- a/packages/runtime-core/src/compat/props.ts +++ b/packages/runtime-core/src/compat/props.ts @@ -1,4 +1,4 @@ -import { DeprecationTypes, warnDeprecation } from './deprecations' +import { DeprecationTypes, warnDeprecation } from './compatConfig' export function createPropsDefaultThis(propKey: string) { return new Proxy( diff --git a/packages/runtime-core/src/compat/renderFn.ts b/packages/runtime-core/src/compat/renderFn.ts index 945c2c2fd..458d9e4e5 100644 --- a/packages/runtime-core/src/compat/renderFn.ts +++ b/packages/runtime-core/src/compat/renderFn.ts @@ -27,8 +27,7 @@ import { VNodeArrayChildren, VNodeProps } from '../vnode' -import { checkCompatEnabled } from './compatConfig' -import { DeprecationTypes } from './deprecations' +import { checkCompatEnabled, DeprecationTypes } from './compatConfig' export function convertLegacyRenderFn(instance: ComponentInternalInstance) { const Component = instance.type as ComponentOptions diff --git a/packages/runtime-core/src/compat/vModel.ts b/packages/runtime-core/src/compat/vModel.ts index d0d8c6af8..c359d17c8 100644 --- a/packages/runtime-core/src/compat/vModel.ts +++ b/packages/runtime-core/src/compat/vModel.ts @@ -3,8 +3,11 @@ import { ComponentInternalInstance, ComponentOptions } from '../component' import { callWithErrorHandling, ErrorCodes } from '../errorHandling' import { VNode } from '../vnode' import { popWarningContext, pushWarningContext } from '../warning' -import { isCompatEnabled } from './compatConfig' -import { DeprecationTypes, warnDeprecation } from './deprecations' +import { + DeprecationTypes, + warnDeprecation, + isCompatEnabled +} from './compatConfig' const defaultModelMapping = { prop: 'value', diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index 3ba0b9d39..be38504bb 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -66,7 +66,7 @@ import { VNodeChild } from './vnode' import { callWithAsyncErrorHandling } from './errorHandling' import { UnionToIntersection } from './helpers/typeUtils' import { deepMergeData } from './compat/data' -import { DeprecationTypes } from './compat/deprecations' +import { DeprecationTypes } from './compat/compatConfig' import { CompatConfig, isCompatEnabled, diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index 46a6b5ef4..1a789b669 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -34,8 +34,8 @@ import { isEmitListener } from './componentEmits' import { InternalObjectKey } from './vnode' import { AppContext } from './apiCreateApp' import { createPropsDefaultThis } from './compat/props' -import { isCompatEnabled } from './compat/compatConfig' -import { DeprecationTypes } from './compat/deprecations' +import { isCompatEnabled, softAssertCompatEnabled } from './compat/compatConfig' +import { DeprecationTypes } from './compat/compatConfig' export type ComponentPropsOptions

= | ComponentObjectPropsOptions

@@ -296,6 +296,15 @@ function setFullProps( if (isReservedProp(key)) { continue } + + if (__COMPAT__ && key.startsWith('onHook:')) { + softAssertCompatEnabled( + DeprecationTypes.INSTANCE_EVENT_HOOKS, + instance, + key.slice(2).toLowerCase() + ) + } + const value = rawProps[key] // prop option names are camelized during normalization, so to support // kebab -> camel conversion here we need to camelize the key. diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 9949ca398..42c5481bb 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -282,11 +282,11 @@ export const ssrUtils = (__NODE_JS__ ? _ssrUtils : null) as typeof _ssrUtils // 2.x COMPAT ------------------------------------------------------------------ -export { DeprecationTypes } from './compat/deprecations' +export { DeprecationTypes } from './compat/compatConfig' export { CompatVue } from './compat/global' export { LegacyConfig } from './compat/globalConfig' -import { warnDeprecation } from './compat/deprecations' +import { warnDeprecation } from './compat/compatConfig' import { createCompatVue } from './compat/global' import { isCompatEnabled, diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 383025892..497c4b3d1 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -86,7 +86,7 @@ import { import { initFeatureFlags } from './featureFlags' import { isAsyncWrapper } from './apiAsyncComponent' import { isCompatEnabled } from './compat/compatConfig' -import { DeprecationTypes } from './compat/deprecations' +import { DeprecationTypes } from './compat/compatConfig' export interface Renderer { render: RootRenderFunction