wip: compiler deprecation config
This commit is contained in:
parent
115372dd5b
commit
e130c7db23
133
packages/compiler-core/src/compat/compatConfig.ts
Normal file
133
packages/compiler-core/src/compat/compatConfig.ts
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import { SourceLocation } from '../ast'
|
||||||
|
import { CompilerError } from '../errors'
|
||||||
|
import { ParserContext } from '../parse'
|
||||||
|
import { TransformContext } from '../transform'
|
||||||
|
|
||||||
|
export type CompilerCompatConfig = Partial<
|
||||||
|
Record<CompilerDeprecationTypes, boolean | 'suppress-warning'>
|
||||||
|
> & {
|
||||||
|
MODE?: 2 | 3
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompilerCompatOptions {
|
||||||
|
compatConfig?: CompilerCompatConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeprecationData = {
|
||||||
|
message: string | ((...args: any[]) => string)
|
||||||
|
link?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
|
||||||
|
[CompilerDeprecationTypes.IS_ON_ELEMENT]: {
|
||||||
|
message: ``,
|
||||||
|
link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
|
||||||
|
},
|
||||||
|
|
||||||
|
[CompilerDeprecationTypes.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 ` +
|
||||||
|
`\`v-model:${key}\`.`,
|
||||||
|
link: `https://v3.vuejs.org/guide/migration/v-model.html`
|
||||||
|
},
|
||||||
|
|
||||||
|
[CompilerDeprecationTypes.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 ` +
|
||||||
|
`before v-bind in the case of conflicting keys. To retain 2.x behavior, ` +
|
||||||
|
`move v-bind to and make it the first attribute. If all occurences ` +
|
||||||
|
`of this warning are working as intended, you can suppress it.`,
|
||||||
|
link: `https://v3.vuejs.org/guide/migration/v-bind.html`
|
||||||
|
},
|
||||||
|
|
||||||
|
[CompilerDeprecationTypes.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]: {
|
||||||
|
message: ``,
|
||||||
|
link: `https://v3.vuejs.org/guide/migration/key-attribute.html#on-conditional-branches`
|
||||||
|
},
|
||||||
|
|
||||||
|
[CompilerDeprecationTypes.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]: {
|
||||||
|
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 ` +
|
||||||
|
`or a computed property that filters v-for data source.`,
|
||||||
|
link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
|
||||||
|
},
|
||||||
|
|
||||||
|
[CompilerDeprecationTypes.NATIVE_TEMPLATE]: {
|
||||||
|
message:
|
||||||
|
`<template> with no special directives will render as a native template` +
|
||||||
|
`element instead of its inner content in Vue 3.`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompatValue(
|
||||||
|
key: CompilerDeprecationTypes,
|
||||||
|
context: ParserContext | TransformContext
|
||||||
|
) {
|
||||||
|
const config = (context as ParserContext).options
|
||||||
|
? (context as ParserContext).options.compatConfig
|
||||||
|
: (context as TransformContext).compatConfig
|
||||||
|
return config && config[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkCompatEnabled(
|
||||||
|
key: CompilerDeprecationTypes,
|
||||||
|
context: ParserContext | TransformContext,
|
||||||
|
loc: SourceLocation | null,
|
||||||
|
...args: any[]
|
||||||
|
): boolean {
|
||||||
|
const enabled = getCompatValue(key, context) !== false
|
||||||
|
if (__DEV__ && enabled) {
|
||||||
|
warnDeprecation(key, context, loc, ...args)
|
||||||
|
}
|
||||||
|
return enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
export function warnDeprecation(
|
||||||
|
key: CompilerDeprecationTypes,
|
||||||
|
context: ParserContext | TransformContext,
|
||||||
|
loc: SourceLocation | null,
|
||||||
|
...args: any[]
|
||||||
|
) {
|
||||||
|
const val = getCompatValue(key, context)
|
||||||
|
if (val === 'suppress-warning') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { message, link } = deprecationData[key]
|
||||||
|
const msg = `(deprecation ${key}) ${
|
||||||
|
typeof message === 'function' ? message(...args) : message
|
||||||
|
}${link ? `\n Details: ${link}` : ``}`
|
||||||
|
|
||||||
|
if (loc) {
|
||||||
|
const err = new SyntaxError(msg) as CompilerError
|
||||||
|
err.code = key
|
||||||
|
err.loc = loc
|
||||||
|
context.onWarn(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
context.onWarn(msg)
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { SourceLocation } from './ast'
|
import { SourceLocation } from './ast'
|
||||||
|
|
||||||
export interface CompilerError extends SyntaxError {
|
export interface CompilerError extends SyntaxError {
|
||||||
code: number
|
code: number | string
|
||||||
loc?: SourceLocation
|
loc?: SourceLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,6 +13,11 @@ export function defaultOnError(error: CompilerError) {
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function defaultOnWarn(msg: string | CompilerError) {
|
||||||
|
__DEV__ &&
|
||||||
|
console.warn(`[Vue warn]`, typeof msg === 'string' ? msg : msg.message)
|
||||||
|
}
|
||||||
|
|
||||||
export function createCompilerError<T extends number>(
|
export function createCompilerError<T extends number>(
|
||||||
code: T,
|
code: T,
|
||||||
loc?: SourceLocation,
|
loc?: SourceLocation,
|
||||||
|
@ -57,3 +57,10 @@ export {
|
|||||||
} from './transforms/transformElement'
|
} from './transforms/transformElement'
|
||||||
export { processSlotOutlet } from './transforms/transformSlotOutlet'
|
export { processSlotOutlet } from './transforms/transformSlotOutlet'
|
||||||
export { generateCodeFrame } from '@vue/shared'
|
export { generateCodeFrame } from '@vue/shared'
|
||||||
|
|
||||||
|
// v2 compat only
|
||||||
|
export {
|
||||||
|
checkCompatEnabled,
|
||||||
|
warnDeprecation,
|
||||||
|
CompilerDeprecationTypes
|
||||||
|
} from './compat/compatConfig'
|
||||||
|
@ -6,9 +6,17 @@ import {
|
|||||||
DirectiveTransform,
|
DirectiveTransform,
|
||||||
TransformContext
|
TransformContext
|
||||||
} from './transform'
|
} from './transform'
|
||||||
|
import { CompilerCompatOptions } from './compat/compatConfig'
|
||||||
import { ParserPlugin } from '@babel/parser'
|
import { ParserPlugin } from '@babel/parser'
|
||||||
|
|
||||||
export interface ParserOptions {
|
export interface ErrorHandlingOptions {
|
||||||
|
onWarn?: (msg: string | CompilerError) => void
|
||||||
|
onError?: (error: CompilerError) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ParserOptions
|
||||||
|
extends ErrorHandlingOptions,
|
||||||
|
CompilerCompatOptions {
|
||||||
/**
|
/**
|
||||||
* e.g. platform native elements, e.g. `<div>` for browsers
|
* e.g. platform native elements, e.g. `<div>` for browsers
|
||||||
*/
|
*/
|
||||||
@ -48,7 +56,6 @@ export interface ParserOptions {
|
|||||||
* Only needed for DOM compilers
|
* Only needed for DOM compilers
|
||||||
*/
|
*/
|
||||||
decodeEntities?: (rawText: string, asAttr: boolean) => string
|
decodeEntities?: (rawText: string, asAttr: boolean) => string
|
||||||
onError?: (error: CompilerError) => void
|
|
||||||
/**
|
/**
|
||||||
* Keep comments in the templates AST, even in production
|
* Keep comments in the templates AST, even in production
|
||||||
*/
|
*/
|
||||||
@ -138,7 +145,10 @@ interface SharedTransformCodegenOptions {
|
|||||||
filename?: string
|
filename?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransformOptions extends SharedTransformCodegenOptions {
|
export interface TransformOptions
|
||||||
|
extends SharedTransformCodegenOptions,
|
||||||
|
ErrorHandlingOptions,
|
||||||
|
CompilerCompatOptions {
|
||||||
/**
|
/**
|
||||||
* An array of node transforms to be applied to every AST node.
|
* An array of node transforms to be applied to every AST node.
|
||||||
*/
|
*/
|
||||||
@ -213,7 +223,6 @@ export interface TransformOptions extends SharedTransformCodegenOptions {
|
|||||||
* needed to render inline CSS variables on component root
|
* needed to render inline CSS variables on component root
|
||||||
*/
|
*/
|
||||||
ssrCssVars?: string
|
ssrCssVars?: string
|
||||||
onError?: (error: CompilerError) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CodegenOptions extends SharedTransformCodegenOptions {
|
export interface CodegenOptions extends SharedTransformCodegenOptions {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import { ParserOptions } from './options'
|
import { ErrorHandlingOptions, ParserOptions } from './options'
|
||||||
import { NO, isArray, makeMap, extend } from '@vue/shared'
|
import { NO, isArray, makeMap, extend } from '@vue/shared'
|
||||||
import { ErrorCodes, createCompilerError, defaultOnError } from './errors'
|
import {
|
||||||
|
ErrorCodes,
|
||||||
|
createCompilerError,
|
||||||
|
defaultOnError,
|
||||||
|
defaultOnWarn
|
||||||
|
} from './errors'
|
||||||
import {
|
import {
|
||||||
assert,
|
assert,
|
||||||
advancePositionWithMutation,
|
advancePositionWithMutation,
|
||||||
@ -25,8 +30,12 @@ import {
|
|||||||
createRoot,
|
createRoot,
|
||||||
ConstantTypes
|
ConstantTypes
|
||||||
} from './ast'
|
} from './ast'
|
||||||
|
import { CompilerCompatOptions } from './compat/compatConfig'
|
||||||
|
|
||||||
type OptionalOptions = 'isNativeTag' | 'isBuiltInComponent'
|
type OptionalOptions =
|
||||||
|
| 'isNativeTag'
|
||||||
|
| 'isBuiltInComponent'
|
||||||
|
| keyof CompilerCompatOptions
|
||||||
type MergedParserOptions = Omit<Required<ParserOptions>, OptionalOptions> &
|
type MergedParserOptions = Omit<Required<ParserOptions>, OptionalOptions> &
|
||||||
Pick<ParserOptions, OptionalOptions>
|
Pick<ParserOptions, OptionalOptions>
|
||||||
type AttributeValue =
|
type AttributeValue =
|
||||||
@ -59,6 +68,7 @@ export const defaultParserOptions: MergedParserOptions = {
|
|||||||
decodeEntities: (rawText: string): string =>
|
decodeEntities: (rawText: string): string =>
|
||||||
rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
|
rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
|
||||||
onError: defaultOnError,
|
onError: defaultOnError,
|
||||||
|
onWarn: defaultOnWarn,
|
||||||
comments: false
|
comments: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +90,7 @@ export interface ParserContext {
|
|||||||
column: number
|
column: number
|
||||||
inPre: boolean // HTML <pre> tag, preserve whitespaces
|
inPre: boolean // HTML <pre> tag, preserve whitespaces
|
||||||
inVPre: boolean // v-pre, do not process directives and interpolations
|
inVPre: boolean // v-pre, do not process directives and interpolations
|
||||||
|
onWarn: NonNullable<ErrorHandlingOptions['onWarn']>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function baseParse(
|
export function baseParse(
|
||||||
@ -111,7 +122,8 @@ function createParserContext(
|
|||||||
originalSource: content,
|
originalSource: content,
|
||||||
source: content,
|
source: content,
|
||||||
inPre: false,
|
inPre: false,
|
||||||
inVPre: false
|
inVPre: false,
|
||||||
|
onWarn: options.onWarn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import {
|
|||||||
capitalize,
|
capitalize,
|
||||||
camelize
|
camelize
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import { defaultOnError } from './errors'
|
import { defaultOnError, defaultOnWarn } from './errors'
|
||||||
import {
|
import {
|
||||||
TO_DISPLAY_STRING,
|
TO_DISPLAY_STRING,
|
||||||
FRAGMENT,
|
FRAGMENT,
|
||||||
@ -40,6 +40,7 @@ import {
|
|||||||
} from './runtimeHelpers'
|
} from './runtimeHelpers'
|
||||||
import { isVSlot } from './utils'
|
import { isVSlot } from './utils'
|
||||||
import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic'
|
import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic'
|
||||||
|
import { CompilerCompatOptions } from './compat/compatConfig'
|
||||||
|
|
||||||
// There are two types of transforms:
|
// There are two types of transforms:
|
||||||
//
|
//
|
||||||
@ -83,7 +84,10 @@ export interface ImportItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TransformContext
|
export interface TransformContext
|
||||||
extends Required<Omit<TransformOptions, 'filename'>> {
|
extends Required<
|
||||||
|
Omit<TransformOptions, 'filename' | keyof CompilerCompatOptions>
|
||||||
|
>,
|
||||||
|
CompilerCompatOptions {
|
||||||
selfName: string | null
|
selfName: string | null
|
||||||
root: RootNode
|
root: RootNode
|
||||||
helpers: Map<symbol, number>
|
helpers: Map<symbol, number>
|
||||||
@ -136,7 +140,9 @@ export function createTransformContext(
|
|||||||
bindingMetadata = EMPTY_OBJ,
|
bindingMetadata = EMPTY_OBJ,
|
||||||
inline = false,
|
inline = false,
|
||||||
isTS = false,
|
isTS = false,
|
||||||
onError = defaultOnError
|
onError = defaultOnError,
|
||||||
|
onWarn = defaultOnWarn,
|
||||||
|
compatConfig
|
||||||
}: TransformOptions
|
}: TransformOptions
|
||||||
): TransformContext {
|
): TransformContext {
|
||||||
const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
|
const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
|
||||||
@ -160,6 +166,8 @@ export function createTransformContext(
|
|||||||
inline,
|
inline,
|
||||||
isTS,
|
isTS,
|
||||||
onError,
|
onError,
|
||||||
|
onWarn,
|
||||||
|
compatConfig,
|
||||||
|
|
||||||
// state
|
// state
|
||||||
root,
|
root,
|
||||||
|
@ -12,12 +12,12 @@ export interface DOMCompilerError extends CompilerError {
|
|||||||
export function createDOMCompilerError(
|
export function createDOMCompilerError(
|
||||||
code: DOMErrorCodes,
|
code: DOMErrorCodes,
|
||||||
loc?: SourceLocation
|
loc?: SourceLocation
|
||||||
): DOMCompilerError {
|
) {
|
||||||
return createCompilerError(
|
return createCompilerError(
|
||||||
code,
|
code,
|
||||||
loc,
|
loc,
|
||||||
__DEV__ || !__BROWSER__ ? DOMErrorMessages : undefined
|
__DEV__ || !__BROWSER__ ? DOMErrorMessages : undefined
|
||||||
)
|
) as DOMCompilerError
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum DOMErrorCodes {
|
export const enum DOMErrorCodes {
|
||||||
|
@ -8,7 +8,9 @@ import {
|
|||||||
createCompoundExpression,
|
createCompoundExpression,
|
||||||
ExpressionNode,
|
ExpressionNode,
|
||||||
SimpleExpressionNode,
|
SimpleExpressionNode,
|
||||||
isStaticExp
|
isStaticExp,
|
||||||
|
warnDeprecation,
|
||||||
|
CompilerDeprecationTypes
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers'
|
import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../runtimeHelpers'
|
||||||
import { makeMap, capitalize } from '@vue/shared'
|
import { makeMap, capitalize } from '@vue/shared'
|
||||||
@ -93,7 +95,11 @@ export const transformOn: DirectiveTransform = (dir, node, context) => {
|
|||||||
if (!modifiers.length) return baseResult
|
if (!modifiers.length) return baseResult
|
||||||
|
|
||||||
if (__COMPAT__ && __DEV__ && modifiers.includes('native')) {
|
if (__COMPAT__ && __DEV__ && modifiers.includes('native')) {
|
||||||
console.warn('.native modifier for v-on has been removed')
|
warnDeprecation(
|
||||||
|
CompilerDeprecationTypes.V_ON_NATIVE_MODIFIER,
|
||||||
|
context,
|
||||||
|
dir.loc
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let { key, value: handlerExp } = baseResult.props[0]
|
let { key, value: handlerExp } = baseResult.props[0]
|
||||||
|
@ -12,8 +12,8 @@ export interface SSRCompilerError extends CompilerError {
|
|||||||
export function createSSRCompilerError(
|
export function createSSRCompilerError(
|
||||||
code: SSRErrorCodes,
|
code: SSRErrorCodes,
|
||||||
loc?: SourceLocation
|
loc?: SourceLocation
|
||||||
): SSRCompilerError {
|
) {
|
||||||
return createCompilerError(code, loc, SSRErrorMessages)
|
return createCompilerError(code, loc, SSRErrorMessages) as SSRCompilerError
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum SSRErrorCodes {
|
export const enum SSRErrorCodes {
|
||||||
|
Loading…
Reference in New Issue
Block a user