From 94e69fd3896214da6ff8b9fb09ad942c598053c7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 8 May 2021 16:47:38 -0400 Subject: [PATCH] fix(compat): handle and warn config.optionMergeStrategies --- .../runtime-core/src/compat/compatConfig.ts | 7 ++++ packages/runtime-core/src/compat/global.ts | 6 ++-- .../runtime-core/src/compat/globalConfig.ts | 32 +++++++++++++++---- packages/vue-compat/README.md | 1 + .../vue-compat/__tests__/globalConfig.spec.ts | 11 ++++++- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/packages/runtime-core/src/compat/compatConfig.ts b/packages/runtime-core/src/compat/compatConfig.ts index 9bcace7c4..053e90d81 100644 --- a/packages/runtime-core/src/compat/compatConfig.ts +++ b/packages/runtime-core/src/compat/compatConfig.ts @@ -26,6 +26,7 @@ export const enum DeprecationTypes { CONFIG_PRODUCTION_TIP = 'CONFIG_PRODUCTION_TIP', CONFIG_IGNORED_ELEMENTS = 'CONFIG_IGNORED_ELEMENTS', CONFIG_WHITESPACE = 'CONFIG_WHITESPACE', + CONFIG_OPTION_MERGE_STRATS = 'CONFIG_OPTION_MERGE_STRATS', INSTANCE_SET = 'INSTANCE_SET', INSTANCE_DELETE = 'INSTANCE_DELETE', @@ -174,6 +175,12 @@ export const deprecationData: Record = { `\`config.compilerOptions.whitespace\`.` }, + [DeprecationTypes.CONFIG_OPTION_MERGE_STRATS]: { + message: + `config.optionMergeStrategies no longer exposes internal strategies. ` + + `Use custom merge functions instead.` + }, + [DeprecationTypes.INSTANCE_SET]: { message: `vm.$set() has been removed as it is no longer needed in Vue 3. ` + diff --git a/packages/runtime-core/src/compat/global.ts b/packages/runtime-core/src/compat/global.ts index da32009f8..8b100254b 100644 --- a/packages/runtime-core/src/compat/global.ts +++ b/packages/runtime-core/src/compat/global.ts @@ -41,7 +41,8 @@ import { Directive } from '../directives' import { nextTick } from '../scheduler' import { version } from '..' import { - installLegacyConfigProperties, + installLegacyConfigWarnings, + installLegacyOptionMergeStrats, LegacyConfig, legacyOptionMergeStrats } from './globalConfig' @@ -327,6 +328,7 @@ export function installAppCompatProperties( render: RootRenderFunction ) { installFilterMethod(app, context) + installLegacyOptionMergeStrats(app.config) if (!singletonApp) { // this is the call of creating the singleton itself so the rest is @@ -337,7 +339,7 @@ export function installAppCompatProperties( installCompatMount(app, context, render) installLegacyAPIs(app) applySingletonAppMutations(app) - if (__DEV__) installLegacyConfigProperties(app.config) + if (__DEV__) installLegacyConfigWarnings(app.config) } function installFilterMethod(app: App, context: AppContext) { diff --git a/packages/runtime-core/src/compat/globalConfig.ts b/packages/runtime-core/src/compat/globalConfig.ts index cd5b4194c..bf7b9189e 100644 --- a/packages/runtime-core/src/compat/globalConfig.ts +++ b/packages/runtime-core/src/compat/globalConfig.ts @@ -1,7 +1,11 @@ import { extend, isArray } from '@vue/shared' import { AppConfig } from '../apiCreateApp' import { mergeDataOption } from './data' -import { DeprecationTypes, warnDeprecation } from './compatConfig' +import { + DeprecationTypes, + softAssertCompatEnabled, + warnDeprecation +} from './compatConfig' import { isCopyingConfig } from './global' // legacy config warnings @@ -33,7 +37,7 @@ export type LegacyConfig = { } // dev only -export function installLegacyConfigProperties(config: AppConfig) { +export function installLegacyConfigWarnings(config: AppConfig) { const legacyConfigOptions: Record = { silent: DeprecationTypes.CONFIG_SILENT, devtools: DeprecationTypes.CONFIG_DEVTOOLS, @@ -57,11 +61,27 @@ export function installLegacyConfigProperties(config: AppConfig) { } }) }) +} - // Internal merge strats which are no longer needed in v3, but we need to - // expose them because some v2 plugins will reuse these internal strats to - // merge their custom options. - extend(config.optionMergeStrategies, legacyOptionMergeStrats) +export function installLegacyOptionMergeStrats(config: AppConfig) { + config.optionMergeStrategies = new Proxy({} as any, { + get(target, key) { + if (key in target) { + return target[key] + } + if ( + key in legacyOptionMergeStrats && + softAssertCompatEnabled( + DeprecationTypes.CONFIG_OPTION_MERGE_STRATS, + null + ) + ) { + return legacyOptionMergeStrats[ + key as keyof typeof legacyOptionMergeStrats + ] + } + } + }) } export const legacyOptionMergeStrats = { diff --git a/packages/vue-compat/README.md b/packages/vue-compat/README.md index 5e13c5bf5..88ea82b39 100644 --- a/packages/vue-compat/README.md +++ b/packages/vue-compat/README.md @@ -321,6 +321,7 @@ Features that start with `COMPILER_` are compiler-specific: if you are using the | GLOBAL_OBSERVABLE | ● | `Vue.observable` removed (use `reactive`) | [link](https://v3.vuejs.org/api/basic-reactivity.html) | | CONFIG_KEY_CODES | ● | config.keyCodes rmeoved | [link](https://v3.vuejs.org/guide/migration/keycode-modifiers.html) | | CONFIG_WHITESPACE | ● | In Vue 3 whitespace defaults to `"condense"` | | +| CONFIG_OPTION_MERGE_STRATS | ● | Vue 3 no longer exposes internal option merge strats | | | INSTANCE_SET | ● | `vm.$set` removed (no longer needed) | | | INSTANCE_DELETE | ● | `vm.$delete` removed (no longer needed) | | | INSTANCE_EVENT_EMITTER | ● | `vm.$on`, `vm.$off`, `vm.$once` removed | [link](https://v3.vuejs.org/guide/migration/events-api.html) | diff --git a/packages/vue-compat/__tests__/globalConfig.spec.ts b/packages/vue-compat/__tests__/globalConfig.spec.ts index af02a218f..f2aa27d4e 100644 --- a/packages/vue-compat/__tests__/globalConfig.spec.ts +++ b/packages/vue-compat/__tests__/globalConfig.spec.ts @@ -1,5 +1,8 @@ import Vue from '@vue/compat' -import { toggleDeprecationWarning } from '../../runtime-core/src/compat/compatConfig' +import { + DeprecationTypes, + toggleDeprecationWarning +} from '../../runtime-core/src/compat/compatConfig' import { createApp } from '../src/esm-index' import { triggerEvent } from './utils' @@ -74,3 +77,9 @@ test('singleton config should affect apps created with createApp()', () => { }).mount(el) expect(el.innerHTML).toBe(``) }) + +test('config.optionMergeStrategies', () => { + toggleDeprecationWarning(true) + expect(typeof Vue.config.optionMergeStrategies.created).toBe('function') + expect(DeprecationTypes.CONFIG_OPTION_MERGE_STRATS).toHaveBeenWarned() +})