From: Evan You Date: Wed, 30 Jun 2021 15:39:31 +0000 (-0400) Subject: refactor(reactivity): improve tree-shaking annotations X-Git-Tag: v3.1.3~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8a6b57dddc9196713e65d737373d73c00e01a78;p=thirdparty%2Fvuejs%2Fcore.git refactor(reactivity): improve tree-shaking annotations --- diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index b5647cb415..a6db361d28 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -42,37 +42,42 @@ const shallowGet = /*#__PURE__*/ createGetter(false, true) const readonlyGet = /*#__PURE__*/ createGetter(true) const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true) -const arrayInstrumentations: Record = {} -// instrument identity-sensitive Array methods to account for possible reactive -// values -;(['includes', 'indexOf', 'lastIndexOf'] as const).forEach(key => { - const method = Array.prototype[key] as any - arrayInstrumentations[key] = function(this: unknown[], ...args: unknown[]) { - const arr = toRaw(this) - for (let i = 0, l = this.length; i < l; i++) { - track(arr, TrackOpTypes.GET, i + '') +const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations() + +function createArrayInstrumentations() { + const instrumentations: Record = {} + // instrument identity-sensitive Array methods to account for possible reactive + // values + ;(['includes', 'indexOf', 'lastIndexOf'] as const).forEach(key => { + const method = Array.prototype[key] as any + instrumentations[key] = function(this: unknown[], ...args: unknown[]) { + const arr = toRaw(this) + for (let i = 0, l = this.length; i < l; i++) { + track(arr, TrackOpTypes.GET, i + '') + } + // we run the method using the original args first (which may be reactive) + const res = method.apply(arr, args) + if (res === -1 || res === false) { + // if that didn't work, run it again using raw values. + return method.apply(arr, args.map(toRaw)) + } else { + return res + } } - // we run the method using the original args first (which may be reactive) - const res = method.apply(arr, args) - if (res === -1 || res === false) { - // if that didn't work, run it again using raw values. - return method.apply(arr, args.map(toRaw)) - } else { + }) + // instrument length-altering mutation methods to avoid length being tracked + // which leads to infinite loops in some cases (#2137) + ;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => { + const method = Array.prototype[key] as any + instrumentations[key] = function(this: unknown[], ...args: unknown[]) { + pauseTracking() + const res = method.apply(this, args) + resetTracking() return res } - } -}) -// instrument length-altering mutation methods to avoid length being tracked -// which leads to infinite loops in some cases (#2137) -;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => { - const method = Array.prototype[key] as any - arrayInstrumentations[key] = function(this: unknown[], ...args: unknown[]) { - pauseTracking() - const res = method.apply(this, args) - resetTracking() - return res - } -}) + }) + return instrumentations +} function createGetter(isReadonly = false, shallow = false) { return function get(target: Target, key: string | symbol, receiver: object) { @@ -224,7 +229,7 @@ export const readonlyHandlers: ProxyHandler = { } } -export const shallowReactiveHandlers: ProxyHandler = extend( +export const shallowReactiveHandlers = /*#__PURE__*/ extend( {}, mutableHandlers, { @@ -236,7 +241,7 @@ export const shallowReactiveHandlers: ProxyHandler = extend( // 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 = extend( +export const shallowReadonlyHandlers = /*#__PURE__*/ extend( {}, readonlyHandlers, { diff --git a/packages/reactivity/src/collectionHandlers.ts b/packages/reactivity/src/collectionHandlers.ts index a0ca8d080d..0d62ba5781 100644 --- a/packages/reactivity/src/collectionHandlers.ts +++ b/packages/reactivity/src/collectionHandlers.ts @@ -236,93 +236,109 @@ function createReadonlyMethod(type: TriggerOpTypes): Function { } } -const mutableInstrumentations: Record = { - get(this: MapTypes, key: unknown) { - return get(this, key) - }, - get size() { - return size((this as unknown) as IterableCollections) - }, - has, - add, - set, - delete: deleteEntry, - clear, - forEach: createForEach(false, false) -} +function createInstrumentations() { + const mutableInstrumentations: Record = { + get(this: MapTypes, key: unknown) { + return get(this, key) + }, + get size() { + return size((this as unknown) as IterableCollections) + }, + has, + add, + set, + delete: deleteEntry, + clear, + forEach: createForEach(false, false) + } -const shallowInstrumentations: Record = { - get(this: MapTypes, key: unknown) { - return get(this, key, false, true) - }, - get size() { - return size((this as unknown) as IterableCollections) - }, - has, - add, - set, - delete: deleteEntry, - clear, - forEach: createForEach(false, true) -} + const shallowInstrumentations: Record = { + get(this: MapTypes, key: unknown) { + return get(this, key, false, true) + }, + get size() { + return size((this as unknown) as IterableCollections) + }, + has, + add, + set, + delete: deleteEntry, + clear, + forEach: createForEach(false, true) + } -const readonlyInstrumentations: Record = { - get(this: MapTypes, key: unknown) { - return get(this, key, true) - }, - get size() { - return size((this as unknown) as IterableCollections, true) - }, - has(this: MapTypes, key: unknown) { - return has.call(this, key, true) - }, - add: createReadonlyMethod(TriggerOpTypes.ADD), - set: createReadonlyMethod(TriggerOpTypes.SET), - delete: createReadonlyMethod(TriggerOpTypes.DELETE), - clear: createReadonlyMethod(TriggerOpTypes.CLEAR), - forEach: createForEach(true, false) -} + const readonlyInstrumentations: Record = { + get(this: MapTypes, key: unknown) { + return get(this, key, true) + }, + get size() { + return size((this as unknown) as IterableCollections, true) + }, + has(this: MapTypes, key: unknown) { + return has.call(this, key, true) + }, + add: createReadonlyMethod(TriggerOpTypes.ADD), + set: createReadonlyMethod(TriggerOpTypes.SET), + delete: createReadonlyMethod(TriggerOpTypes.DELETE), + clear: createReadonlyMethod(TriggerOpTypes.CLEAR), + forEach: createForEach(true, false) + } -const shallowReadonlyInstrumentations: Record = { - get(this: MapTypes, key: unknown) { - return get(this, key, true, true) - }, - get size() { - return size((this as unknown) as IterableCollections, true) - }, - has(this: MapTypes, key: unknown) { - return has.call(this, key, true) - }, - add: createReadonlyMethod(TriggerOpTypes.ADD), - set: createReadonlyMethod(TriggerOpTypes.SET), - delete: createReadonlyMethod(TriggerOpTypes.DELETE), - clear: createReadonlyMethod(TriggerOpTypes.CLEAR), - forEach: createForEach(true, true) + const shallowReadonlyInstrumentations: Record = { + get(this: MapTypes, key: unknown) { + return get(this, key, true, true) + }, + get size() { + return size((this as unknown) as IterableCollections, true) + }, + has(this: MapTypes, key: unknown) { + return has.call(this, key, true) + }, + add: createReadonlyMethod(TriggerOpTypes.ADD), + set: createReadonlyMethod(TriggerOpTypes.SET), + delete: createReadonlyMethod(TriggerOpTypes.DELETE), + clear: createReadonlyMethod(TriggerOpTypes.CLEAR), + forEach: createForEach(true, true) + } + + const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator] + iteratorMethods.forEach(method => { + mutableInstrumentations[method as string] = createIterableMethod( + method, + false, + false + ) + readonlyInstrumentations[method as string] = createIterableMethod( + method, + true, + false + ) + shallowInstrumentations[method as string] = createIterableMethod( + method, + false, + true + ) + shallowReadonlyInstrumentations[method as string] = createIterableMethod( + method, + true, + true + ) + }) + + return [ + mutableInstrumentations, + readonlyInstrumentations, + shallowInstrumentations, + shallowReadonlyInstrumentations + ] } -const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator] -iteratorMethods.forEach(method => { - mutableInstrumentations[method as string] = createIterableMethod( - method, - false, - false - ) - readonlyInstrumentations[method as string] = createIterableMethod( - method, - true, - false - ) - shallowInstrumentations[method as string] = createIterableMethod( - method, - false, - true - ) - shallowReadonlyInstrumentations[method as string] = createIterableMethod( - method, - true, - true - ) -}) +const [ + mutableInstrumentations, + readonlyInstrumentations, + shallowInstrumentations, + shallowReadonlyInstrumentations +] = /* #__PURE__*/ createInstrumentations() function createInstrumentationGetter(isReadonly: boolean, shallow: boolean) { const instrumentations = shallow @@ -357,21 +373,21 @@ function createInstrumentationGetter(isReadonly: boolean, shallow: boolean) { } export const mutableCollectionHandlers: ProxyHandler = { - get: createInstrumentationGetter(false, false) + get: /*#__PURE__*/ createInstrumentationGetter(false, false) } export const shallowCollectionHandlers: ProxyHandler = { - get: createInstrumentationGetter(false, true) + get: /*#__PURE__*/ createInstrumentationGetter(false, true) } export const readonlyCollectionHandlers: ProxyHandler = { - get: createInstrumentationGetter(true, false) + get: /*#__PURE__*/ createInstrumentationGetter(true, false) } export const shallowReadonlyCollectionHandlers: ProxyHandler< CollectionTypes > = { - get: createInstrumentationGetter(true, true) + get: /*#__PURE__*/ createInstrumentationGetter(true, true) } function checkIdentityKeys(