Skip to content

Commit bbf708d

Browse files
committed
wip: support configuring compiler deprecations at runtime + warn invalid deprecation configs
1 parent 79cbf21 commit bbf708d

File tree

5 files changed

+72
-22
lines changed

5 files changed

+72
-22
lines changed

packages/compiler-core/src/compat/compatConfig.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ export interface CompilerCompatOptions {
1414
}
1515

1616
export const enum CompilerDeprecationTypes {
17-
IS_ON_ELEMENT = 'IS_ON_ELEMENT',
18-
V_BIND_SYNC = 'V_BIND_SYNC',
19-
V_BIND_OBJECT_ORDER = 'V_BIND_OBJECT_ORDER',
20-
V_ON_NATIVE_MODIFIER = 'V_ON_NATIVE_MODIFIER',
21-
KEY_V_IF = 'KEY_V_IF',
22-
KEY_V_FOR_TEMPLATE = 'KEY_V_FOR_TEMPLATE',
23-
V_IF_V_FOR_PRECEDENCE = 'V_IF_V_FOR_PRECEDENCE',
24-
NATIVE_TEMPLATE = 'NATIVE_TEMPLATE'
17+
COMPILER_IS_ON_ELEMENT = 'COMPILER_IS_ON_ELEMENT',
18+
COMPILER_V_BIND_SYNC = 'COMPILER_V_BIND_SYNC',
19+
COMPILER_V_BIND_OBJECT_ORDER = 'COMPILER_V_BIND_OBJECT_ORDER',
20+
COMPILER_V_ON_NATIVE_MODIFIER = 'COMPILER_V_ON_NATIVE_MODIFIER',
21+
COMPILER_KEY_V_IF = 'COMPILER_KEY_V_IF',
22+
COMPILER_KEY_V_FOR_TEMPLATE = 'COMPILER_KEY_V_FOR_TEMPLATE',
23+
COMPILER_V_IF_V_FOR_PRECEDENCE = 'COMPILER_V_IF_V_FOR_PRECEDENCE',
24+
COMPILER_NATIVE_TEMPLATE = 'COMPILER_NATIVE_TEMPLATE'
2525
}
2626

2727
type DeprecationData = {
@@ -30,23 +30,23 @@ type DeprecationData = {
3030
}
3131

3232
const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
33-
[CompilerDeprecationTypes.IS_ON_ELEMENT]: {
33+
[CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT]: {
3434
message:
3535
`Platform-native elements with "is" prop will no longer be ` +
3636
`treated as components in Vue 3 unless the "is" value is explicitly ` +
3737
`prefixed with "vue:".`,
3838
link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
3939
},
4040

41-
[CompilerDeprecationTypes.V_BIND_SYNC]: {
41+
[CompilerDeprecationTypes.COMPILER_V_BIND_SYNC]: {
4242
message: key =>
4343
`.sync modifier for v-bind has been removed. Use v-model with ` +
4444
`argument instead. \`v-bind:${key}.sync\` should be changed to ` +
4545
`\`v-model:${key}\`.`,
4646
link: `https://v3.vuejs.org/guide/migration/v-model.html`
4747
},
4848

49-
[CompilerDeprecationTypes.V_BIND_OBJECT_ORDER]: {
49+
[CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER]: {
5050
message:
5151
`v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
5252
`object spread: it will now overwrite an existing attribute that appears ` +
@@ -56,30 +56,30 @@ const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
5656
link: `https://v3.vuejs.org/guide/migration/v-bind.html`
5757
},
5858

59-
[CompilerDeprecationTypes.V_ON_NATIVE_MODIFIER]: {
59+
[CompilerDeprecationTypes.COMPILER_V_ON_NATIVE_MODIFIER]: {
6060
message: `.native modifier for v-on has been removed as is no longer necessary.`,
6161
link: `https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html`
6262
},
6363

64-
[CompilerDeprecationTypes.KEY_V_IF]: {
64+
[CompilerDeprecationTypes.COMPILER_KEY_V_IF]: {
6565
message: ``,
6666
link: `https://v3.vuejs.org/guide/migration/key-attribute.html#on-conditional-branches`
6767
},
6868

69-
[CompilerDeprecationTypes.KEY_V_FOR_TEMPLATE]: {
69+
[CompilerDeprecationTypes.COMPILER_KEY_V_FOR_TEMPLATE]: {
7070
message: ``,
7171
link: `https://v3.vuejs.org/guide/migration/key-attribute.html#with-template-v-for`
7272
},
7373

74-
[CompilerDeprecationTypes.V_IF_V_FOR_PRECEDENCE]: {
74+
[CompilerDeprecationTypes.COMPILER_V_IF_V_FOR_PRECEDENCE]: {
7575
message:
7676
`v-if / v-for precedence when used on the same element has changed ` +
7777
`in Vue 3. It is best to avoid the ambiguity with either <template> tags ` +
7878
`or a computed property that filters v-for data source.`,
7979
link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
8080
},
8181

82-
[CompilerDeprecationTypes.NATIVE_TEMPLATE]: {
82+
[CompilerDeprecationTypes.COMPILER_NATIVE_TEMPLATE]: {
8383
message:
8484
`<template> with no special directives will render as a native template` +
8585
`element instead of its inner content in Vue 3.`

packages/compiler-core/src/parse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ function parseTag(
517517
if (
518518
__COMPAT__ &&
519519
checkCompatEnabled(
520-
CompilerDeprecationTypes.IS_ON_ELEMENT,
520+
CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT,
521521
context,
522522
p.loc
523523
)

packages/compiler-dom/src/transforms/vOn.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export const transformOn: DirectiveTransform = (dir, node, context) => {
9696

9797
if (__COMPAT__ && __DEV__ && modifiers.includes('native')) {
9898
warnDeprecation(
99-
CompilerDeprecationTypes.V_ON_NATIVE_MODIFIER,
99+
CompilerDeprecationTypes.COMPILER_V_ON_NATIVE_MODIFIER,
100100
context,
101101
dir.loc
102102
)

packages/runtime-core/src/compat/compatConfig.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,12 +456,48 @@ export type CompatConfig = Partial<
456456
MODE?: 2 | 3
457457
}
458458

459-
const globalCompatConfig: CompatConfig = {}
459+
export const globalCompatConfig: CompatConfig = {}
460460

461461
export function configureCompat(config: CompatConfig) {
462+
if (__DEV__) {
463+
validateCompatConfig(config)
464+
}
462465
extend(globalCompatConfig, config)
463466
}
464467

468+
const seenConfigObjects = /*#__PURE__*/ new WeakSet<CompatConfig>()
469+
const warnedInvalidKeys: Record<string, boolean> = {}
470+
471+
// dev only
472+
export function validateCompatConfig(config: CompatConfig) {
473+
if (seenConfigObjects.has(config)) {
474+
return
475+
}
476+
seenConfigObjects.add(config)
477+
478+
for (const key of Object.keys(config)) {
479+
if (
480+
key !== 'MODE' &&
481+
!(key in deprecationData) &&
482+
!(key in warnedInvalidKeys)
483+
) {
484+
if (key.startsWith('COMPILER_')) {
485+
if (isRuntimeOnly()) {
486+
warn(
487+
`Depreaction config "${key}" is compiler-specific and you are ` +
488+
`running a runtime-only build of Vue. This deprecation should be ` +
489+
`configured via compiler options in your build setup instead.`
490+
// TODO link to migration build docs on build setup
491+
)
492+
}
493+
} else {
494+
warn(`Invalid deprecation config "${key}".`)
495+
}
496+
warnedInvalidKeys[key] = true
497+
}
498+
}
499+
}
500+
465501
export function getCompatConfigForKey(
466502
key: DeprecationTypes | 'MODE',
467503
instance: ComponentInternalInstance | null

packages/runtime-core/src/component.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@ import {
4747
NO,
4848
makeMap,
4949
isPromise,
50-
ShapeFlags
50+
ShapeFlags,
51+
extend
5152
} from '@vue/shared'
5253
import { SuspenseBoundary } from './components/Suspense'
5354
import { CompilerOptions } from '@vue/compiler-core'
5455
import { markAttrsAccessed } from './componentRenderUtils'
5556
import { currentRenderingInstance } from './componentRenderContext'
5657
import { startMeasure, endMeasure } from './profiling'
5758
import { convertLegacyRenderFn } from './compat/renderFn'
59+
import { globalCompatConfig, validateCompatConfig } from './compat/compatConfig'
5860

5961
export type Data = Record<string, unknown>
6062

@@ -692,6 +694,10 @@ export function finishComponentSetup(
692694

693695
if (__COMPAT__) {
694696
convertLegacyRenderFn(instance)
697+
698+
if (__DEV__ && Component.compatConfig) {
699+
validateCompatConfig(Component.compatConfig)
700+
}
695701
}
696702

697703
// template / render function normalization
@@ -710,10 +716,18 @@ export function finishComponentSetup(
710716
if (__DEV__) {
711717
startMeasure(instance, `compile`)
712718
}
713-
Component.render = compile(Component.template, {
719+
const compilerOptions: CompilerOptions = {
714720
isCustomElement: instance.appContext.config.isCustomElement,
715721
delimiters: Component.delimiters
716-
})
722+
}
723+
if (__COMPAT__) {
724+
// pass runtime compat config into the compiler
725+
compilerOptions.compatConfig = Object.create(globalCompatConfig)
726+
if (Component.compatConfig) {
727+
extend(compilerOptions.compatConfig, Component.compatConfig)
728+
}
729+
}
730+
Component.render = compile(Component.template, compilerOptions)
717731
if (__DEV__) {
718732
endMeasure(instance, `compile`)
719733
}

0 commit comments

Comments
 (0)