workflow: setup eslint for prohibited syntax and globals

fix #1285
This commit is contained in:
Evan You
2020-06-10 16:54:23 -04:00
parent e4dc03a8b1
commit 80c868aefe
20 changed files with 697 additions and 149 deletions

View File

@@ -3,7 +3,7 @@ import { baseParse } from './parse'
import { transform, NodeTransform, DirectiveTransform } from './transform'
import { generate, CodegenResult } from './codegen'
import { RootNode } from './ast'
import { isString } from '@vue/shared'
import { isString, extend } from '@vue/shared'
import { transformIf } from './transforms/vIf'
import { transformFor } from './transforms/vFor'
import { transformExpression } from './transforms/transformExpression'
@@ -80,21 +80,26 @@ export function baseCompile(
const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(
prefixIdentifiers
)
transform(ast, {
...options,
prefixIdentifiers,
nodeTransforms: [
...nodeTransforms,
...(options.nodeTransforms || []) // user transforms
],
directiveTransforms: {
...directiveTransforms,
...(options.directiveTransforms || {}) // user transforms
}
})
transform(
ast,
extend({}, options, {
prefixIdentifiers,
nodeTransforms: [
...nodeTransforms,
...(options.nodeTransforms || []) // user transforms
],
directiveTransforms: extend(
{},
directiveTransforms,
options.directiveTransforms || {} // user transforms
)
})
)
return generate(ast, {
...options,
prefixIdentifiers
})
return generate(
ast,
extend({}, options, {
prefixIdentifiers
})
)
}

View File

@@ -1,5 +1,5 @@
import { ParserOptions } from './options'
import { NO, isArray, makeMap } from '@vue/shared'
import { NO, isArray, makeMap, extend } from '@vue/shared'
import { ErrorCodes, createCompilerError, defaultOnError } from './errors'
import {
assert,
@@ -24,7 +24,6 @@ import {
InterpolationNode,
createRoot
} from './ast'
import { extend } from '@vue/shared'
type OptionalOptions = 'isNativeTag' | 'isBuiltInComponent'
type MergedParserOptions = Omit<Required<ParserOptions>, OptionalOptions> &
@@ -91,10 +90,7 @@ function createParserContext(
options: ParserOptions
): ParserContext {
return {
options: {
...defaultParserOptions,
...options
},
options: extend({}, defaultParserOptions, options),
column: 1,
line: 1,
offset: 0,

View File

@@ -30,7 +30,7 @@ import {
KEEP_ALIVE,
BASE_TRANSITION
} from './runtimeHelpers'
import { isString, isObject, hyphenate } from '@vue/shared'
import { isString, isObject, hyphenate, extend } from '@vue/shared'
import { parse } from '@babel/parser'
import { walk } from 'estree-walker'
import { Node } from '@babel/types'
@@ -119,7 +119,11 @@ export function advancePositionWithClone(
source: string,
numberOfCharacters: number = source.length
): Position {
return advancePositionWithMutation({ ...pos }, source, numberOfCharacters)
return advancePositionWithMutation(
extend({}, pos),
source,
numberOfCharacters
)
}
// advance by mutation without cloning (for performance reasons), since this

View File

@@ -1,3 +1,5 @@
/* eslint-disable no-restricted-globals */
let decoder: HTMLDivElement
export function decodeHtmlBrowser(raw: string): string {

View File

@@ -18,6 +18,7 @@ import { transformOn } from './transforms/vOn'
import { transformShow } from './transforms/vShow'
import { warnTransitionChildren } from './transforms/warnTransitionChildren'
import { stringifyStatic } from './transforms/stringifyStatic'
import { extend } from '@vue/shared'
export { parserOptions }
@@ -39,23 +40,22 @@ export function compile(
template: string,
options: CompilerOptions = {}
): CodegenResult {
return baseCompile(template, {
...parserOptions,
...options,
nodeTransforms: [...DOMNodeTransforms, ...(options.nodeTransforms || [])],
directiveTransforms: {
...DOMDirectiveTransforms,
...(options.directiveTransforms || {})
},
transformHoist: __BROWSER__ ? null : stringifyStatic
})
return baseCompile(
template,
extend({}, parserOptions, options, {
nodeTransforms: [...DOMNodeTransforms, ...(options.nodeTransforms || [])],
directiveTransforms: extend(
{},
DOMDirectiveTransforms,
options.directiveTransforms || {}
),
transformHoist: __BROWSER__ ? null : stringifyStatic
})
)
}
export function parse(template: string, options: ParserOptions = {}): RootNode {
return baseParse(template, {
...parserOptions,
...options
})
return baseParse(template, extend({}, parserOptions, options))
}
export * from './runtimeHelpers'

View File

@@ -1,7 +1,14 @@
import { reactive, readonly, toRaw, ReactiveFlags } from './reactive'
import { TrackOpTypes, TriggerOpTypes } from './operations'
import { track, trigger, ITERATE_KEY } from './effect'
import { isObject, hasOwn, isSymbol, hasChanged, isArray } from '@vue/shared'
import {
isObject,
hasOwn,
isSymbol,
hasChanged,
isArray,
extend
} from '@vue/shared'
import { isRef } from './ref'
const builtInSymbols = new Set(
@@ -167,16 +174,22 @@ export const readonlyHandlers: ProxyHandler<object> = {
}
}
export const shallowReactiveHandlers: ProxyHandler<object> = {
...mutableHandlers,
get: shallowGet,
set: shallowSet
}
export const shallowReactiveHandlers: ProxyHandler<object> = extend(
{},
mutableHandlers,
{
get: shallowGet,
set: shallowSet
}
)
// Props handlers are special in the sense that it should not unwrap top-level
// refs (in order to allow refs to be explicitly passed down), but should
// retain the reactivity of the normal readonly object.
export const shallowReadonlyHandlers: ProxyHandler<object> = {
...readonlyHandlers,
get: shallowReadonlyGet
}
export const shallowReadonlyHandlers: ProxyHandler<object> = extend(
{},
readonlyHandlers,
{
get: shallowReadonlyGet
}
)

View File

@@ -14,7 +14,8 @@ import {
makeMap,
isReservedProp,
EMPTY_ARR,
def
def,
extend
} from '@vue/shared'
import { warn } from './warning'
import {
@@ -308,7 +309,7 @@ export function normalizePropsOptions(
if (__FEATURE_OPTIONS__ && !isFunction(comp)) {
const extendProps = (raw: ComponentOptions) => {
const [props, keys] = normalizePropsOptions(raw)
Object.assign(normalized, props)
extend(normalized, props)
if (keys) needCastKeys.push(...keys)
}
if (comp.extends) {

View File

@@ -1,7 +1,13 @@
import { ComponentInternalInstance, Data } from './component'
import { nextTick, queueJob } from './scheduler'
import { instanceWatch } from './apiWatch'
import { EMPTY_OBJ, hasOwn, isGloballyWhitelisted, NOOP } from '@vue/shared'
import {
EMPTY_OBJ,
hasOwn,
isGloballyWhitelisted,
NOOP,
extend
} from '@vue/shared'
import {
ReactiveEffect,
UnwrapRef,
@@ -365,27 +371,30 @@ if (__DEV__ && !__TEST__) {
}
}
export const RuntimeCompiledPublicInstanceProxyHandlers = {
...PublicInstanceProxyHandlers,
get(target: ComponentRenderContext, key: string) {
// fast path for unscopables when using `with` block
if ((key as any) === Symbol.unscopables) {
return
export const RuntimeCompiledPublicInstanceProxyHandlers = extend(
{},
PublicInstanceProxyHandlers,
{
get(target: ComponentRenderContext, key: string) {
// fast path for unscopables when using `with` block
if ((key as any) === Symbol.unscopables) {
return
}
return PublicInstanceProxyHandlers.get!(target, key, target)
},
has(_: ComponentRenderContext, key: string) {
const has = key[0] !== '_' && !isGloballyWhitelisted(key)
if (__DEV__ && !has && PublicInstanceProxyHandlers.has!(_, key)) {
warn(
`Property ${JSON.stringify(
key
)} should not start with _ which is a reserved prefix for Vue internals.`
)
}
return has
}
return PublicInstanceProxyHandlers.get!(target, key, target)
},
has(_: ComponentRenderContext, key: string) {
const has = key[0] !== '_' && !isGloballyWhitelisted(key)
if (__DEV__ && !has && PublicInstanceProxyHandlers.has!(_, key)) {
warn(
`Property ${JSON.stringify(
key
)} should not start with _ which is a reserved prefix for Vue internals.`
)
}
return has
}
}
)
// In dev mode, the proxy target exposes the same properties as seen on `this`
// for easier console inspection. In prod mode it will be an empty object so

View File

@@ -495,6 +495,7 @@ function hydrateSuspense(
optimized: boolean
) => Node | null
): Node | null {
/* eslint-disable no-restricted-globals */
const suspense = (vnode.suspense = createSuspenseBoundary(
vnode,
parentSuspense,
@@ -524,6 +525,7 @@ function hydrateSuspense(
suspense.resolve()
}
return result
/* eslint-enable no-restricted-globals */
}
export function normalizeSuspenseChildren(

View File

@@ -1,9 +1,11 @@
/* eslint-disable no-restricted-globals */
import {
ComponentInternalInstance,
ComponentOptions,
InternalRenderFunction
} from './component'
import { queueJob, queuePostFlushCb } from './scheduler'
import { extend } from '@vue/shared'
export interface HMRRuntime {
createRecord: typeof createRecord
@@ -85,7 +87,7 @@ function reload(id: string, newComp: ComponentOptions) {
const comp = instance.type
if (!comp.__hmrUpdated) {
// 1. Update existing comp definition to match new one
Object.assign(comp, newComp)
extend(comp, newComp)
for (const key in comp) {
if (!(key in newComp)) {
delete (comp as any)[key]

View File

@@ -31,11 +31,13 @@ function isSupported() {
if (supported !== undefined) {
return supported
}
/* eslint-disable no-restricted-globals */
if (typeof window !== 'undefined' && window.performance) {
supported = true
perf = window.performance
} else {
supported = false
}
/* eslint-enable no-restricted-globals */
return supported
}

View File

@@ -7,7 +7,7 @@ import {
getCurrentInstance,
callWithAsyncErrorHandling
} from '@vue/runtime-core'
import { isObject, toNumber } from '@vue/shared'
import { isObject, toNumber, extend } from '@vue/shared'
import { ErrorCodes } from 'packages/runtime-core/src/errorHandling'
const TRANSITION = 'transition'
@@ -39,8 +39,7 @@ export const Transition: FunctionalComponent<TransitionProps> = (
Transition.inheritRef = true
export const TransitionPropsValidators = (Transition.props = {
...(BaseTransition as any).props,
const DOMTransitionPropsValidators = {
name: String,
type: String,
css: {
@@ -57,24 +56,40 @@ export const TransitionPropsValidators = (Transition.props = {
leaveFromClass: String,
leaveActiveClass: String,
leaveToClass: String
})
}
export const TransitionPropsValidators = (Transition.props = extend(
{},
(BaseTransition as any).props,
DOMTransitionPropsValidators
))
export function resolveTransitionProps(
rawProps: TransitionProps
): BaseTransitionProps<Element> {
let {
name = 'v',
type,
css = true,
duration,
enterFromClass = `${name}-enter-from`,
enterActiveClass = `${name}-enter-active`,
enterToClass = `${name}-enter-to`,
appearFromClass = enterFromClass,
appearActiveClass = enterActiveClass,
appearToClass = enterToClass,
leaveFromClass = `${name}-leave-from`,
leaveActiveClass = `${name}-leave-active`,
leaveToClass = `${name}-leave-to`
} = rawProps
const baseProps: BaseTransitionProps<Element> = {}
for (const key in rawProps) {
if (!(key in DOMTransitionPropsValidators)) {
;(baseProps as any)[key] = (rawProps as any)[key]
}
}
export function resolveTransitionProps({
name = 'v',
type,
css = true,
duration,
enterFromClass = `${name}-enter-from`,
enterActiveClass = `${name}-enter-active`,
enterToClass = `${name}-enter-to`,
appearFromClass = enterFromClass,
appearActiveClass = enterActiveClass,
appearToClass = enterToClass,
leaveFromClass = `${name}-leave-from`,
leaveActiveClass = `${name}-leave-active`,
leaveToClass = `${name}-leave-to`,
...baseProps
}: TransitionProps): BaseTransitionProps<Element> {
if (!css) {
return baseProps
}
@@ -117,8 +132,7 @@ export function resolveTransitionProps({
callWithAsyncErrorHandling(hook, instance, ErrorCodes.TRANSITION_HOOK, args)
}
return {
...baseProps,
return extend(baseProps, {
onBeforeEnter(el) {
onBeforeEnter && onBeforeEnter(el)
addTransitionClass(el, enterActiveClass)
@@ -158,7 +172,7 @@ export function resolveTransitionProps({
},
onEnterCancelled: finishEnter,
onLeaveCancelled: finishLeave
}
} as BaseTransitionProps<Element>)
}
function normalizeDuration(

View File

@@ -21,6 +21,7 @@ import {
SetupContext
} from '@vue/runtime-core'
import { toRaw } from '@vue/reactivity'
import { extend } from '@vue/shared'
interface Position {
top: number
@@ -36,11 +37,10 @@ export type TransitionGroupProps = Omit<TransitionProps, 'mode'> & {
}
const TransitionGroupImpl = {
props: {
...TransitionPropsValidators,
props: extend({}, TransitionPropsValidators, {
tag: String,
moveClass: String
},
}),
setup(props: TransitionGroupProps, { slots }: SetupContext) {
const instance = getCurrentInstance()!

View File

@@ -12,7 +12,7 @@ import {
import { nodeOps } from './nodeOps'
import { patchProp } from './patchProp'
// Importing from the compiler, will be tree-shaken in prod
import { isFunction, isString, isHTMLTag, isSVGTag } from '@vue/shared'
import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared'
declare module '@vue/reactivity' {
export interface RefUnwrapBailTypes {
@@ -21,10 +21,7 @@ declare module '@vue/reactivity' {
}
}
const rendererOptions = {
patchProp,
...nodeOps
}
const rendererOptions = extend({ patchProp }, nodeOps)
// lazy create the renderer - this makes core renderer logic tree-shakable
// in case the user only imports reactivity utilities from Vue.

View File

@@ -7,11 +7,11 @@ import {
import { nodeOps, TestElement } from './nodeOps'
import { patchProp } from './patchProp'
import { serializeInner } from './serialize'
import { extend } from '@vue/shared'
const { render: baseRender, createApp: baseCreateApp } = createRenderer({
patchProp,
...nodeOps
})
const { render: baseRender, createApp: baseCreateApp } = createRenderer(
extend({ patchProp }, nodeOps)
)
export const render = baseRender as RootRenderFunction<TestElement>
export const createApp = baseCreateApp as CreateAppFunction<TestElement>

View File

@@ -28,15 +28,7 @@ export const NO = () => false
const onRE = /^on[^a-z]/
export const isOn = (key: string) => onRE.test(key)
export const extend = <T extends object, U extends object>(
a: T,
b: U
): T & U => {
for (const key in b) {
;(a as any)[key] = b[key]
}
return a as any
}
export const extend = Object.assign
export const remove = <T>(arr: T[], el: T) => {
const i = arr.indexOf(el)

View File

@@ -4,7 +4,7 @@ import './devCheck'
import { compile, CompilerOptions, CompilerError } from '@vue/compiler-dom'
import { registerRuntimeCompiler, RenderFunction, warn } from '@vue/runtime-dom'
import * as runtimeDom from '@vue/runtime-dom'
import { isString, NOOP, generateCodeFrame } from '@vue/shared'
import { isString, NOOP, generateCodeFrame, extend } from '@vue/shared'
const compileCache: Record<string, RenderFunction> = Object.create(null)
@@ -39,25 +39,30 @@ function compileToFunction(
template = el ? el.innerHTML : ``
}
const { code } = compile(template, {
hoistStatic: true,
onError(err: CompilerError) {
if (__DEV__) {
const message = `Template compilation error: ${err.message}`
const codeFrame =
err.loc &&
generateCodeFrame(
template as string,
err.loc.start.offset,
err.loc.end.offset
)
warn(codeFrame ? `${message}\n${codeFrame}` : message)
} else {
throw err
}
},
...options
})
const { code } = compile(
template,
extend(
{
hoistStatic: true,
onError(err: CompilerError) {
if (__DEV__) {
const message = `Template compilation error: ${err.message}`
const codeFrame =
err.loc &&
generateCodeFrame(
template as string,
err.loc.start.offset,
err.loc.end.offset
)
warn(codeFrame ? `${message}\n${codeFrame}` : message)
} else {
throw err
}
}
},
options
)
)
// The wildcard import results in a huge object with every export
// with keys that cannot be mangled, and can be quite heavy size-wise.