]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: support configuring compiler deprecations at runtime + warn invalid deprecation...
authorEvan You <yyx990803@gmail.com>
Fri, 16 Apr 2021 16:19:12 +0000 (12:19 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 16 Apr 2021 16:19:12 +0000 (12:19 -0400)
packages/compiler-core/src/compat/compatConfig.ts
packages/compiler-core/src/parse.ts
packages/compiler-dom/src/transforms/vOn.ts
packages/runtime-core/src/compat/compatConfig.ts
packages/runtime-core/src/component.ts

index 3c69e00c8f544854019147087a0aa6b4ce1d83b5..f5acca1b62011e06b85330d66e812bd4af99e124 100644 (file)
@@ -14,14 +14,14 @@ export interface CompilerCompatOptions {
 }
 
 export const enum CompilerDeprecationTypes {
-  IS_ON_ELEMENT = 'IS_ON_ELEMENT',
-  V_BIND_SYNC = 'V_BIND_SYNC',
-  V_BIND_OBJECT_ORDER = 'V_BIND_OBJECT_ORDER',
-  V_ON_NATIVE_MODIFIER = 'V_ON_NATIVE_MODIFIER',
-  KEY_V_IF = 'KEY_V_IF',
-  KEY_V_FOR_TEMPLATE = 'KEY_V_FOR_TEMPLATE',
-  V_IF_V_FOR_PRECEDENCE = 'V_IF_V_FOR_PRECEDENCE',
-  NATIVE_TEMPLATE = 'NATIVE_TEMPLATE'
+  COMPILER_IS_ON_ELEMENT = 'COMPILER_IS_ON_ELEMENT',
+  COMPILER_V_BIND_SYNC = 'COMPILER_V_BIND_SYNC',
+  COMPILER_V_BIND_OBJECT_ORDER = 'COMPILER_V_BIND_OBJECT_ORDER',
+  COMPILER_V_ON_NATIVE_MODIFIER = 'COMPILER_V_ON_NATIVE_MODIFIER',
+  COMPILER_KEY_V_IF = 'COMPILER_KEY_V_IF',
+  COMPILER_KEY_V_FOR_TEMPLATE = 'COMPILER_KEY_V_FOR_TEMPLATE',
+  COMPILER_V_IF_V_FOR_PRECEDENCE = 'COMPILER_V_IF_V_FOR_PRECEDENCE',
+  COMPILER_NATIVE_TEMPLATE = 'COMPILER_NATIVE_TEMPLATE'
 }
 
 type DeprecationData = {
@@ -30,7 +30,7 @@ type DeprecationData = {
 }
 
 const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
-  [CompilerDeprecationTypes.IS_ON_ELEMENT]: {
+  [CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT]: {
     message:
       `Platform-native elements with "is" prop will no longer be ` +
       `treated as components in Vue 3 unless the "is" value is explicitly ` +
@@ -38,7 +38,7 @@ const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
     link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
   },
 
-  [CompilerDeprecationTypes.V_BIND_SYNC]: {
+  [CompilerDeprecationTypes.COMPILER_V_BIND_SYNC]: {
     message: key =>
       `.sync modifier for v-bind has been removed. Use v-model with ` +
       `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
@@ -46,7 +46,7 @@ const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
     link: `https://v3.vuejs.org/guide/migration/v-model.html`
   },
 
-  [CompilerDeprecationTypes.V_BIND_OBJECT_ORDER]: {
+  [CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER]: {
     message:
       `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
       `object spread: it will now overwrite an existing attribute that appears ` +
@@ -56,22 +56,22 @@ const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
     link: `https://v3.vuejs.org/guide/migration/v-bind.html`
   },
 
-  [CompilerDeprecationTypes.V_ON_NATIVE_MODIFIER]: {
+  [CompilerDeprecationTypes.COMPILER_V_ON_NATIVE_MODIFIER]: {
     message: `.native modifier for v-on has been removed as is no longer necessary.`,
     link: `https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html`
   },
 
-  [CompilerDeprecationTypes.KEY_V_IF]: {
+  [CompilerDeprecationTypes.COMPILER_KEY_V_IF]: {
     message: ``,
     link: `https://v3.vuejs.org/guide/migration/key-attribute.html#on-conditional-branches`
   },
 
-  [CompilerDeprecationTypes.KEY_V_FOR_TEMPLATE]: {
+  [CompilerDeprecationTypes.COMPILER_KEY_V_FOR_TEMPLATE]: {
     message: ``,
     link: `https://v3.vuejs.org/guide/migration/key-attribute.html#with-template-v-for`
   },
 
-  [CompilerDeprecationTypes.V_IF_V_FOR_PRECEDENCE]: {
+  [CompilerDeprecationTypes.COMPILER_V_IF_V_FOR_PRECEDENCE]: {
     message:
       `v-if / v-for precedence when used on the same element has changed ` +
       `in Vue 3. It is best to avoid the ambiguity with either <template> tags ` +
@@ -79,7 +79,7 @@ const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
     link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
   },
 
-  [CompilerDeprecationTypes.NATIVE_TEMPLATE]: {
+  [CompilerDeprecationTypes.COMPILER_NATIVE_TEMPLATE]: {
     message:
       `<template> with no special directives will render as a native template` +
       `element instead of its inner content in Vue 3.`
index 01bfa5e0537c0044ce7c8eac8b99ac99668198f8..055d76b1f7fcfcc797190c121f31e48b5ca82e0a 100644 (file)
@@ -517,7 +517,7 @@ function parseTag(
       if (
         __COMPAT__ &&
         checkCompatEnabled(
-          CompilerDeprecationTypes.IS_ON_ELEMENT,
+          CompilerDeprecationTypes.COMPILER_IS_ON_ELEMENT,
           context,
           p.loc
         )
index 25eeaa25bc7bad0410f12dc66037f688e772a413..7ce57dfaa7b5305bba4e1b2f4779080fc7d8fad6 100644 (file)
@@ -96,7 +96,7 @@ export const transformOn: DirectiveTransform = (dir, node, context) => {
 
     if (__COMPAT__ && __DEV__ && modifiers.includes('native')) {
       warnDeprecation(
-        CompilerDeprecationTypes.V_ON_NATIVE_MODIFIER,
+        CompilerDeprecationTypes.COMPILER_V_ON_NATIVE_MODIFIER,
         context,
         dir.loc
       )
index 5f53785923611235f532f3a202999ceba8f49f3e..807bfc12f413a97bddc176b25118e9b3b5a63395 100644 (file)
@@ -456,12 +456,48 @@ export type CompatConfig = Partial<
   MODE?: 2 | 3
 }
 
-const globalCompatConfig: CompatConfig = {}
+export const globalCompatConfig: CompatConfig = {}
 
 export function configureCompat(config: CompatConfig) {
+  if (__DEV__) {
+    validateCompatConfig(config)
+  }
   extend(globalCompatConfig, config)
 }
 
+const seenConfigObjects = /*#__PURE__*/ new WeakSet<CompatConfig>()
+const warnedInvalidKeys: Record<string, boolean> = {}
+
+// dev only
+export function validateCompatConfig(config: CompatConfig) {
+  if (seenConfigObjects.has(config)) {
+    return
+  }
+  seenConfigObjects.add(config)
+
+  for (const key of Object.keys(config)) {
+    if (
+      key !== 'MODE' &&
+      !(key in deprecationData) &&
+      !(key in warnedInvalidKeys)
+    ) {
+      if (key.startsWith('COMPILER_')) {
+        if (isRuntimeOnly()) {
+          warn(
+            `Depreaction config "${key}" is compiler-specific and you are ` +
+              `running a runtime-only build of Vue. This deprecation should be ` +
+              `configured via compiler options in your build setup instead.`
+            // TODO link to migration build docs on build setup
+          )
+        }
+      } else {
+        warn(`Invalid deprecation config "${key}".`)
+      }
+      warnedInvalidKeys[key] = true
+    }
+  }
+}
+
 export function getCompatConfigForKey(
   key: DeprecationTypes | 'MODE',
   instance: ComponentInternalInstance | null
index d0e729457a5264e7f33e5a7e84a64933206a3bc8..8323144e9070804f8e51db638da08dd15ccda424 100644 (file)
@@ -47,7 +47,8 @@ import {
   NO,
   makeMap,
   isPromise,
-  ShapeFlags
+  ShapeFlags,
+  extend
 } from '@vue/shared'
 import { SuspenseBoundary } from './components/Suspense'
 import { CompilerOptions } from '@vue/compiler-core'
@@ -55,6 +56,7 @@ import { markAttrsAccessed } from './componentRenderUtils'
 import { currentRenderingInstance } from './componentRenderContext'
 import { startMeasure, endMeasure } from './profiling'
 import { convertLegacyRenderFn } from './compat/renderFn'
+import { globalCompatConfig, validateCompatConfig } from './compat/compatConfig'
 
 export type Data = Record<string, unknown>
 
@@ -692,6 +694,10 @@ export function finishComponentSetup(
 
   if (__COMPAT__) {
     convertLegacyRenderFn(instance)
+
+    if (__DEV__ && Component.compatConfig) {
+      validateCompatConfig(Component.compatConfig)
+    }
   }
 
   // template / render function normalization
@@ -710,10 +716,18 @@ export function finishComponentSetup(
       if (__DEV__) {
         startMeasure(instance, `compile`)
       }
-      Component.render = compile(Component.template, {
+      const compilerOptions: CompilerOptions = {
         isCustomElement: instance.appContext.config.isCustomElement,
         delimiters: Component.delimiters
-      })
+      }
+      if (__COMPAT__) {
+        // pass runtime compat config into the compiler
+        compilerOptions.compatConfig = Object.create(globalCompatConfig)
+        if (Component.compatConfig) {
+          extend(compilerOptions.compatConfig, Component.compatConfig)
+        }
+      }
+      Component.render = compile(Component.template, compilerOptions)
       if (__DEV__) {
         endMeasure(instance, `compile`)
       }