From 67099fe20299a51f9974f0e2f9ef19ca05efe92b Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 6 May 2022 16:49:15 +0800 Subject: [PATCH 01/86] fix(runtime-core): ensure consistent behavior between dev/prod on invalid v-for range close #5867 --- packages/runtime-core/__tests__/helpers/renderList.spec.ts | 4 +++- packages/runtime-core/src/helpers/renderList.ts | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/__tests__/helpers/renderList.spec.ts b/packages/runtime-core/__tests__/helpers/renderList.spec.ts index 06d2825df..ae487b6be 100644 --- a/packages/runtime-core/__tests__/helpers/renderList.spec.ts +++ b/packages/runtime-core/__tests__/helpers/renderList.spec.ts @@ -22,7 +22,9 @@ describe('renderList', () => { }) it('should warn when given a non-integer N', () => { - renderList(3.1, () => {}) + try { + renderList(3.1, () => {}) + } catch (e) {} expect( `The v-for range expect an integer value but got 3.1.` ).toHaveBeenWarned() diff --git a/packages/runtime-core/src/helpers/renderList.ts b/packages/runtime-core/src/helpers/renderList.ts index 9fbf967a8..1655d555f 100644 --- a/packages/runtime-core/src/helpers/renderList.ts +++ b/packages/runtime-core/src/helpers/renderList.ts @@ -67,7 +67,6 @@ export function renderList( } else if (typeof source === 'number') { if (__DEV__ && !Number.isInteger(source)) { warn(`The v-for range expect an integer value but got ${source}.`) - return [] } ret = new Array(source) for (let i = 0; i < source; i++) { From 32e53bfd478af895dd090ea6c8766fa043e179e4 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Fri, 6 May 2022 10:07:49 +0100 Subject: [PATCH 02/86] fix(types): keep the original type when unwrapping `markRaw` (#3791) --- packages/reactivity/src/reactive.ts | 6 +++-- packages/reactivity/src/ref.ts | 2 ++ test-dts/index.d.ts | 6 ++--- test-dts/reactivity.test-d.ts | 42 +++++++++++++++++++++++++++-- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/packages/reactivity/src/reactive.ts b/packages/reactivity/src/reactive.ts index f160b2111..ce689012d 100644 --- a/packages/reactivity/src/reactive.ts +++ b/packages/reactivity/src/reactive.ts @@ -11,7 +11,7 @@ import { shallowCollectionHandlers, shallowReadonlyCollectionHandlers } from './collectionHandlers' -import { UnwrapRefSimple, Ref } from './ref' +import { UnwrapRefSimple, Ref, RawSymbol } from './ref' export const enum ReactiveFlags { SKIP = '__v_skip', @@ -241,7 +241,9 @@ export function toRaw(observed: T): T { return raw ? toRaw(raw) : observed } -export function markRaw(value: T): T { +export function markRaw( + value: T +): T & { [RawSymbol]?: true } { def(value, ReactiveFlags.SKIP, true) return value } diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 22dd432b9..2a3b3732e 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -12,6 +12,7 @@ import { CollectionTypes } from './collectionHandlers' import { createDep, Dep } from './dep' declare const RefSymbol: unique symbol +export declare const RawSymbol: unique symbol export interface Ref { value: T @@ -291,6 +292,7 @@ export type UnwrapRefSimple = T extends | BaseTypes | Ref | RefUnwrapBailTypes[keyof RefUnwrapBailTypes] + | { [RawSymbol]?: true } ? T : T extends Array ? { [K in keyof T]: UnwrapRefSimple } diff --git a/test-dts/index.d.ts b/test-dts/index.d.ts index 59eadcb92..d0eeb6a7b 100644 --- a/test-dts/index.d.ts +++ b/test-dts/index.d.ts @@ -9,9 +9,9 @@ export function expectType(value: T): void export function expectError(value: T): void export function expectAssignable(value: T2): void -export type IsUnion = (T extends any - ? (U extends T ? false : true) - : never) extends false +export type IsUnion = ( + T extends any ? (U extends T ? false : true) : never +) extends false ? false : true diff --git a/test-dts/reactivity.test-d.ts b/test-dts/reactivity.test-d.ts index 4c22765e7..0499c6da2 100644 --- a/test-dts/reactivity.test-d.ts +++ b/test-dts/reactivity.test-d.ts @@ -1,5 +1,14 @@ -import { shallowReadonly } from '@vue/reactivity' -import { ref, readonly, describe, expectError, expectType, Ref } from './index' +import { + ref, + readonly, + shallowReadonly, + describe, + expectError, + expectType, + Ref, + reactive, + markRaw +} from './index' describe('should support DeepReadonly', () => { const r = readonly({ obj: { k: 'v' } }) @@ -15,6 +24,35 @@ describe('readonly ref', () => { expectType(r) }) +describe('should support markRaw', () => { + class Test { + item = {} as Ref + } + const test = new Test() + const plain = { + ref: ref(1) + } + + const r = reactive({ + class: { + raw: markRaw(test), + reactive: test + }, + plain: { + raw: markRaw(plain), + reactive: plain + } + }) + + expectType>(r.class.raw) + // @ts-expect-error it should unwrap + expectType>(r.class.reactive) + + expectType>(r.plain.raw.ref) + // @ts-expect-error it should unwrap + expectType>(r.plain.reactive.ref) +}) + describe('shallowReadonly ref unwrap', () => { const r = shallowReadonly({ count: { n: ref(1) } }) // @ts-expect-error From 98b821d94a0a0fb4d7701809da6bec331a47e6e5 Mon Sep 17 00:00:00 2001 From: Zclhlmgqzc <31752986+Zclhlmgqzc@users.noreply.github.com> Date: Fri, 6 May 2022 17:44:05 +0800 Subject: [PATCH 03/86] fix(types): preserve and expose original options on defineComponent return type (#5416) fix #3796 --- .../runtime-core/src/apiAsyncComponent.ts | 2 +- .../runtime-core/src/apiDefineComponent.ts | 155 +++++++++----- packages/runtime-core/src/componentOptions.ts | 26 ++- .../src/componentPublicInstance.ts | 20 +- test-dts/defineComponent.test-d.tsx | 195 ++++++++++-------- 5 files changed, 242 insertions(+), 156 deletions(-) diff --git a/packages/runtime-core/src/apiAsyncComponent.ts b/packages/runtime-core/src/apiAsyncComponent.ts index 8825eefa5..dc92b90d7 100644 --- a/packages/runtime-core/src/apiAsyncComponent.ts +++ b/packages/runtime-core/src/apiAsyncComponent.ts @@ -111,7 +111,7 @@ export function defineAsyncComponent< ) } - return defineComponent({ + return defineComponent<{}>({ name: 'AsyncComponentWrapper', __asyncLoader: load, diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 83446346f..f0f69af34 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -6,7 +6,8 @@ import { ComponentOptionsWithObjectProps, ComponentOptionsMixin, RenderFunction, - ComponentOptionsBase + ComponentOptionsBase, + ComponentProvideOptions } from './componentOptions' import { SetupContext, @@ -40,6 +41,8 @@ export type DefineComponent< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = {}, EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, + RawOptions extends {} = {}, PP = PublicProps, Props = Readonly< PropsOrPropOptions extends ComponentPropsOptions @@ -48,22 +51,23 @@ export type DefineComponent< > & ({} extends E ? {} : EmitsToProps), Defaults = ExtractDefaultPropTypes -> = ComponentPublicInstanceConstructor< - CreateComponentPublicInstance< - Props, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - PP & Props, - Defaults, - true +> = RawOptions & + ComponentPublicInstanceConstructor< + CreateComponentPublicInstance< + Props, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + PP & Props, + Defaults, + true + > & + Props > & - Props -> & ComponentOptionsBase< Props, RawBindings, @@ -74,7 +78,8 @@ export type DefineComponent< Extends, E, EE, - Defaults + Defaults, + Provide > & PP @@ -104,20 +109,36 @@ export function defineComponent< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, - EE extends string = string + EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, + Options extends {} = {} >( - options: ComponentOptionsWithoutProps< - Props, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE - > -): DefineComponent + options: Options & + ComponentOptionsWithoutProps< + Props, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + Provide + > +): DefineComponent< + Props, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + Provide, + Options +> // overload 3: object format with array props declaration // props inferred as { [key in PropNames]?: any } @@ -131,19 +152,23 @@ export function defineComponent< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record, - EE extends string = string + EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, + Options extends {} = {} >( - options: ComponentOptionsWithArrayProps< - PropNames, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE - > + options: Options & + ComponentOptionsWithArrayProps< + PropNames, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + Provide + > ): DefineComponent< Readonly<{ [key in PropNames]?: any }>, RawBindings, @@ -153,7 +178,9 @@ export function defineComponent< Mixin, Extends, E, - EE + EE, + Provide, + Options > // overload 4: object format with object props declaration @@ -169,20 +196,36 @@ export function defineComponent< Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record, - EE extends string = string + EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, + Options extends {} = {} >( - options: ComponentOptionsWithObjectProps< - PropsOptions, - RawBindings, - D, - C, - M, - Mixin, - Extends, - E, - EE - > -): DefineComponent + options: Options & + ComponentOptionsWithObjectProps< + PropsOptions, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + Provide + > +): DefineComponent< + PropsOptions, + RawBindings, + D, + C, + M, + Mixin, + Extends, + E, + EE, + Provide, + Options +> // implementation, close to no-op export function defineComponent(options: unknown) { diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index e8fa676a2..b4fd47905 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -117,8 +117,9 @@ export interface ComponentOptionsBase< Extends extends ComponentOptionsMixin, E extends EmitsOptions, EE extends string = string, - Defaults = {} -> extends LegacyOptions, + Defaults = {}, + Provide extends ComponentProvideOptions = ComponentProvideOptions +> extends LegacyOptions, ComponentInternalOptions, ComponentCustomOptions { setup?: ( @@ -224,6 +225,7 @@ export type ComponentOptionsWithoutProps< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, PE = Props & EmitsToProps > = ComponentOptionsBase< PE, @@ -235,7 +237,8 @@ export type ComponentOptionsWithoutProps< Extends, E, EE, - {} + {}, + Provide > & { props?: undefined } & ThisType< @@ -252,6 +255,7 @@ export type ComponentOptionsWithArrayProps< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, Props = Readonly<{ [key in PropNames]?: any }> & EmitsToProps > = ComponentOptionsBase< Props, @@ -263,7 +267,8 @@ export type ComponentOptionsWithArrayProps< Extends, E, EE, - {} + {}, + Provide > & { props: PropNames[] } & ThisType< @@ -289,6 +294,7 @@ export type ComponentOptionsWithObjectProps< Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = EmitsOptions, EE extends string = string, + Provide extends ComponentProvideOptions = ComponentProvideOptions, Props = Readonly> & EmitsToProps, Defaults = ExtractDefaultPropTypes > = ComponentOptionsBase< @@ -301,7 +307,8 @@ export type ComponentOptionsWithObjectProps< Extends, E, EE, - Defaults + Defaults, + Provide > & { props: PropsOptions & ThisType } & ThisType< @@ -384,6 +391,10 @@ type ComponentWatchOptionItem = WatchOptionItem | WatchOptionItem[] type ComponentWatchOptions = Record +export type ComponentProvideOptions = ObjectProvideOptions | Function + +type ObjectProvideOptions = Record + type ComponentInjectOptions = string[] | ObjectInjectOptions type ObjectInjectOptions = Record< @@ -397,7 +408,8 @@ interface LegacyOptions< C extends ComputedOptions, M extends MethodOptions, Mixin extends ComponentOptionsMixin, - Extends extends ComponentOptionsMixin + Extends extends ComponentOptionsMixin, + Provide extends ComponentProvideOptions = ComponentProvideOptions > { compatConfig?: CompatConfig @@ -431,7 +443,7 @@ interface LegacyOptions< computed?: C methods?: M watch?: ComponentWatchOptions - provide?: Data | Function + provide?: Provide inject?: ComponentInjectOptions // assets diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index 03ee0e0e9..faae5312d 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -34,7 +34,8 @@ import { OptionTypesKeys, resolveMergedOptions, shouldCacheAccess, - MergedComponentOptionsOverride + MergedComponentOptionsOverride, + ComponentProvideOptions } from './componentOptions' import { EmitsOptions, EmitFn } from './componentEmits' import { Slots } from './componentSlots' @@ -150,7 +151,8 @@ export type CreateComponentPublicInstance< PublicM extends MethodOptions = UnwrapMixinsType & EnsureNonVoid, PublicDefaults = UnwrapMixinsType & - EnsureNonVoid + EnsureNonVoid, + Provide extends ComponentProvideOptions = ComponentProvideOptions > = ComponentPublicInstance< PublicP, PublicB, @@ -161,7 +163,19 @@ export type CreateComponentPublicInstance< PublicProps, PublicDefaults, MakeDefaultsOptional, - ComponentOptionsBase + ComponentOptionsBase< + P, + B, + D, + C, + M, + Mixin, + Extends, + E, + string, + Defaults, + Provide + > > // public properties exposed on the proxy, which is used as the render context diff --git a/test-dts/defineComponent.test-d.tsx b/test-dts/defineComponent.test-d.tsx index 031b4a13e..3c4e9cb39 100644 --- a/test-dts/defineComponent.test-d.tsx +++ b/test-dts/defineComponent.test-d.tsx @@ -49,96 +49,98 @@ describe('with object props', () => { type GT = string & { __brand: unknown } - const MyComponent = defineComponent({ - props: { - a: Number, - // required should make property non-void - b: { - type: String, - required: true - }, - e: Function, - h: Boolean, - j: Function as PropType string | undefined)>, - // default value should infer type and make it non-void - bb: { - default: 'hello' - }, - bbb: { - // Note: default function value requires arrow syntax + explicit - // annotation - default: (props: any) => (props.bb as string) || 'foo' - }, - bbbb: { - type: String, - default: undefined - }, - bbbbb: { - type: String, - default: () => undefined - }, - // explicit type casting - cc: Array as PropType, - // required + type casting - dd: { - type: Object as PropType<{ n: 1 }>, - required: true - }, - // return type - ee: Function as PropType<() => string>, - // arguments + object return - ff: Function as PropType<(a: number, b: string) => { a: boolean }>, - // explicit type casting with constructor - ccc: Array as () => string[], - // required + constructor type casting - ddd: { - type: Array as () => string[], - required: true - }, - // required + object return - eee: { - type: Function as PropType<() => { a: string }>, - required: true - }, - // required + arguments + object return - fff: { - type: Function as PropType<(a: number, b: string) => { a: boolean }>, - required: true - }, - hhh: { - type: Boolean, - required: true - }, - // default + type casting - ggg: { - type: String as PropType<'foo' | 'bar'>, - default: 'foo' - }, - // default + function - ffff: { - type: Function as PropType<(a: number, b: string) => { a: boolean }>, - default: (a: number, b: string) => ({ a: a > +b }) - }, - // union + function with different return types - iii: Function as PropType<(() => string) | (() => number)>, - // union + function with different args & same return type - jjj: { - type: Function as PropType< - ((arg1: string) => string) | ((arg1: string, arg2: string) => string) - >, - required: true - }, - kkk: null, - validated: { - type: String, - // validator requires explicit annotation - validator: (val: unknown) => val !== '' - }, - date: Date, - l: [Date], - ll: [Date, Number], - lll: [String, Number] + const props = { + a: Number, + // required should make property non-void + b: { + type: String, + required: true as true }, + e: Function, + h: Boolean, + j: Function as PropType string | undefined)>, + // default value should infer type and make it non-void + bb: { + default: 'hello' + }, + bbb: { + // Note: default function value requires arrow syntax + explicit + // annotation + default: (props: any) => (props.bb as string) || 'foo' + }, + bbbb: { + type: String, + default: undefined + }, + bbbbb: { + type: String, + default: () => undefined + }, + // explicit type casting + cc: Array as PropType, + // required + type casting + dd: { + type: Object as PropType<{ n: 1 }>, + required: true as true + }, + // return type + ee: Function as PropType<() => string>, + // arguments + object return + ff: Function as PropType<(a: number, b: string) => { a: boolean }>, + // explicit type casting with constructor + ccc: Array as () => string[], + // required + constructor type casting + ddd: { + type: Array as () => string[], + required: true as true + }, + // required + object return + eee: { + type: Function as PropType<() => { a: string }>, + required: true as true + }, + // required + arguments + object return + fff: { + type: Function as PropType<(a: number, b: string) => { a: boolean }>, + required: true as true + }, + hhh: { + type: Boolean, + required: true as true + }, + // default + type casting + ggg: { + type: String as PropType<'foo' | 'bar'>, + default: 'foo' + }, + // default + function + ffff: { + type: Function as PropType<(a: number, b: string) => { a: boolean }>, + default: (a: number, b: string) => ({ a: a > +b }) + }, + // union + function with different return types + iii: Function as PropType<(() => string) | (() => number)>, + // union + function with different args & same return type + jjj: { + type: Function as PropType< + ((arg1: string) => string) | ((arg1: string, arg2: string) => string) + >, + required: true as true + }, + kkk: null, + validated: { + type: String, + // validator requires explicit annotation + validator: (val: unknown) => val !== '' + }, + date: Date, + l: [Date], + ll: [Date, Number], + lll: [String, Number] + } + + const MyComponent = defineComponent({ + props, setup(props) { // type assertion. See https://github.com/SamVerschueren/tsd expectType(props.a) @@ -188,6 +190,9 @@ describe('with object props', () => { }) } }, + provide() { + return {} + }, render() { const props = this.$props expectType(props.a) @@ -258,6 +263,18 @@ describe('with object props', () => { expectType(MyComponent) + expectType(MyComponent.props) + // @ts-expect-error it should be an object and not any + expectError<[]>(MyComponent.props) + + expectType<() => {}>(MyComponent.provide) + // @ts-expect-error + expectError<[]>(MyComponent.provide) + + expectType<() => null>(MyComponent.render) + + expectType(defineComponent({}).render) + // Test TSX expectType( Date: Fri, 6 May 2022 18:42:22 +0800 Subject: [PATCH 04/86] refactor(reactivity): make some expression simpler (#5131) --- packages/reactivity/src/baseHandlers.ts | 5 ++--- packages/reactivity/src/collectionHandlers.ts | 16 ++++++++++------ packages/runtime-core/src/renderer.ts | 5 ++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts index 81dce9b96..7e564f29d 100644 --- a/packages/reactivity/src/baseHandlers.ts +++ b/packages/reactivity/src/baseHandlers.ts @@ -125,9 +125,8 @@ function createGetter(isReadonly = false, shallow = false) { } if (isRef(res)) { - // ref unwrapping - does not apply for Array + integer key. - const shouldUnwrap = !targetIsArray || !isIntegerKey(key) - return shouldUnwrap ? res.value : res + // ref unwrapping - skip unwrap for Array + integer key. + return targetIsArray && isIntegerKey(key) ? res : res.value } if (isObject(res)) { diff --git a/packages/reactivity/src/collectionHandlers.ts b/packages/reactivity/src/collectionHandlers.ts index 0e9e19e82..09365f960 100644 --- a/packages/reactivity/src/collectionHandlers.ts +++ b/packages/reactivity/src/collectionHandlers.ts @@ -26,10 +26,12 @@ function get( target = (target as any)[ReactiveFlags.RAW] const rawTarget = toRaw(target) const rawKey = toRaw(key) - if (key !== rawKey) { - !isReadonly && track(rawTarget, TrackOpTypes.GET, key) + if (!isReadonly) { + if (key !== rawKey) { + track(rawTarget, TrackOpTypes.GET, key) + } + track(rawTarget, TrackOpTypes.GET, rawKey) } - !isReadonly && track(rawTarget, TrackOpTypes.GET, rawKey) const { has } = getProto(rawTarget) const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive if (has.call(rawTarget, key)) { @@ -47,10 +49,12 @@ function has(this: CollectionTypes, key: unknown, isReadonly = false): boolean { const target = (this as any)[ReactiveFlags.RAW] const rawTarget = toRaw(target) const rawKey = toRaw(key) - if (key !== rawKey) { - !isReadonly && track(rawTarget, TrackOpTypes.HAS, key) + if (!isReadonly) { + if (key !== rawKey) { + track(rawTarget, TrackOpTypes.HAS, key) + } + track(rawTarget, TrackOpTypes.HAS, rawKey) } - !isReadonly && track(rawTarget, TrackOpTypes.HAS, rawKey) return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index ed698d21f..33fe7a23d 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -1544,11 +1544,11 @@ function baseCreateRenderer( // create reactive effect for rendering const effect = (instance.effect = new ReactiveEffect( componentUpdateFn, - () => queueJob(instance.update), + () => queueJob(update), instance.scope // track it in component's effect scope )) - const update = (instance.update = effect.run.bind(effect) as SchedulerJob) + const update: SchedulerJob = (instance.update = () => effect.run()) update.id = instance.uid // allowRecurse // #1801, #2043 component render effects should allow recursive updates @@ -1561,7 +1561,6 @@ function baseCreateRenderer( effect.onTrigger = instance.rtg ? e => invokeArrayFns(instance.rtg!, e) : void 0 - // @ts-ignore (for scheduler) update.ownerInstance = instance } From 292ce6943940049afe79d4f20b1047b4651b9b04 Mon Sep 17 00:00:00 2001 From: qinxiaosen_ccc <33564028+senmu-a@users.noreply.github.com> Date: Fri, 6 May 2022 18:44:28 +0800 Subject: [PATCH 05/86] chore: remove outdated type comment (#5103) --- packages/runtime-core/src/apiCreateApp.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index 8b437f2bf..6b2093141 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -345,9 +345,8 @@ export function createAppAPI( `It will be overwritten with the new value.` ) } - // TypeScript doesn't allow symbols as index type - // https://github.com/Microsoft/TypeScript/issues/24587 - context.provides[key as string] = value + + context.provides[key as string | symbol] = value return app } From 0683a022ec83694e29636f64aaf3c04012e9a7f0 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 7 May 2022 10:37:07 +0800 Subject: [PATCH 06/86] types(reactivity-transform): improve type readability for reactive variables --- packages/vue/macros.d.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/vue/macros.d.ts b/packages/vue/macros.d.ts index a0a9f54d3..41aefd77d 100644 --- a/packages/vue/macros.d.ts +++ b/packages/vue/macros.d.ts @@ -16,17 +16,21 @@ export declare const enum RefTypes { WritableComputedRef = 3 } -type RefValue = T extends null | undefined - ? T - : T & { [RefType]?: RefTypes.Ref } +type RefValue = T extends null | undefined ? T : ReactiveVariable -type ComputedRefValue = T extends null | undefined - ? T - : T & { [RefType]?: RefTypes.ComputedRef } +type ReactiveVariable = T & { [RefType]?: RefTypes.Ref } + +type ComputedRefValue = T extends null | undefined ? T : ComputedVariable + +type ComputedVariable = T & { [RefType]?: RefTypes.ComputedRef } type WritableComputedRefValue = T extends null | undefined ? T - : T & { [RefType]?: RefTypes.WritableComputedRef } + : WritableComputedVariable + +type WritableComputedVariable = T & { + [RefType]?: RefTypes.WritableComputedRef +} type NormalObject = T & { [RefType]?: never } From 7dfe146096487a98ba1733598c44407bc89a1b9f Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 08:39:27 +0800 Subject: [PATCH 07/86] fix(compiler-sfc): fix object default values for reactive props destructure --- .../compileScriptPropsTransform.spec.ts.snap | 8 ++++---- .../__tests__/compileScriptPropsTransform.spec.ts | 8 ++++---- packages/compiler-sfc/src/compileScript.ts | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap index 7105dfe38..8a7359420 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScriptPropsTransform.spec.ts.snap @@ -65,7 +65,7 @@ exports[`sfc props transform default values w/ runtime declaration 1`] = ` export default { props: _mergeDefaults(['foo', 'bar'], { foo: 1, - bar: () => {} + bar: () => ({}) }), setup(__props) { @@ -83,7 +83,7 @@ exports[`sfc props transform default values w/ type declaration 1`] = ` export default /*#__PURE__*/_defineComponent({ props: { foo: { type: Number, required: false, default: 1 }, - bar: { type: Object, required: false, default: () => {} } + bar: { type: Object, required: false, default: () => ({}) } }, setup(__props: any) { @@ -101,11 +101,11 @@ exports[`sfc props transform default values w/ type declaration, prod mode 1`] = export default /*#__PURE__*/_defineComponent({ props: { foo: { default: 1 }, - bar: { default: () => {} }, + bar: { default: () => ({}) }, baz: null, boola: { type: Boolean }, boolb: { type: [Boolean, Number] }, - func: { type: Function, default: () => () => {} } + func: { type: Function, default: () => (() => {}) } }, setup(__props: any) { diff --git a/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts b/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts index 140dbec2e..e7fbb31c3 100644 --- a/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScriptPropsTransform.spec.ts @@ -59,7 +59,7 @@ describe('sfc props transform', () => { // function expect(content).toMatch(`props: _mergeDefaults(['foo', 'bar'], { foo: 1, - bar: () => {} + bar: () => ({}) })`) assertCode(content) }) @@ -74,7 +74,7 @@ describe('sfc props transform', () => { // function expect(content).toMatch(`props: { foo: { type: Number, required: false, default: 1 }, - bar: { type: Object, required: false, default: () => {} } + bar: { type: Object, required: false, default: () => ({}) } }`) assertCode(content) }) @@ -92,11 +92,11 @@ describe('sfc props transform', () => { // function expect(content).toMatch(`props: { foo: { default: 1 }, - bar: { default: () => {} }, + bar: { default: () => ({}) }, baz: null, boola: { type: Boolean }, boolb: { type: [Boolean, Number] }, - func: { type: Function, default: () => () => {} } + func: { type: Function, default: () => (() => {}) } }`) assertCode(content) }) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index f70faeaf0..3a3a26033 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -735,7 +735,7 @@ export function compileScript( destructured.default.end! ) const isLiteral = destructured.default.type.endsWith('Literal') - return isLiteral ? value : `() => ${value}` + return isLiteral ? value : `() => (${value})` } } From 16939241b0f64cefea254b024a9b5a25caea93d9 Mon Sep 17 00:00:00 2001 From: ygj6 <7699524+ygj6@users.noreply.github.com> Date: Tue, 10 May 2022 09:16:28 +0800 Subject: [PATCH 08/86] fix(compiler-sfc): automatically infer component name from filename when using script setup (#4997) close #4993 --- .../__snapshots__/compileScript.spec.ts.snap | 43 +++++++++++++++ .../__tests__/compileScript.spec.ts | 55 +++++++++++++++++++ packages/compiler-sfc/__tests__/utils.ts | 12 +++- packages/compiler-sfc/src/compileScript.ts | 28 +++++++++- packages/compiler-sfc/src/parse.ts | 4 +- 5 files changed, 137 insertions(+), 5 deletions(-) diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap index de223bf91..cbe274ef9 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap @@ -1,5 +1,48 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`SFC analyze + `, + undefined, + { + filename: 'FooBar.vue' + } + ) + expect(content).toMatch(`export default { + name: 'FooBar'`) + assertCode(content) + }) + + test('do not overwrite manual name (object)', () => { + const { content } = compile( + ` + + `, + undefined, + { + filename: 'FooBar.vue' + } + ) + expect(content).not.toMatch(`name: 'FooBar'`) + expect(content).toMatch(`name: 'Baz'`) + assertCode(content) + }) + + test('do not overwrite manual name (call)', () => { + const { content } = compile( + ` + + `, + undefined, + { + filename: 'FooBar.vue' + } + ) + expect(content).not.toMatch(`name: 'FooBar'`) + expect(content).toMatch(`name: 'Baz'`) + assertCode(content) + }) + }) }) diff --git a/packages/compiler-sfc/__tests__/utils.ts b/packages/compiler-sfc/__tests__/utils.ts index 206ff3681..ffa12652c 100644 --- a/packages/compiler-sfc/__tests__/utils.ts +++ b/packages/compiler-sfc/__tests__/utils.ts @@ -1,13 +1,19 @@ -import { parse, SFCScriptCompileOptions, compileScript } from '../src' +import { + parse, + SFCScriptCompileOptions, + compileScript, + SFCParseOptions +} from '../src' import { parse as babelParse } from '@babel/parser' export const mockId = 'xxxxxxxx' export function compileSFCScript( src: string, - options?: Partial + options?: Partial, + parseOptions?: SFCParseOptions ) { - const { descriptor } = parse(src) + const { descriptor } = parse(src, parseOptions) return compileScript(descriptor, { ...options, id: mockId diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 3a3a26033..7c84f29b3 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -11,7 +11,7 @@ import { isFunctionType, walkIdentifiers } from '@vue/compiler-dom' -import { SFCDescriptor, SFCScriptBlock } from './parse' +import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse' import { parse as _parse, ParserOptions, ParserPlugin } from '@babel/parser' import { camelize, capitalize, generateCodeFrame, makeMap } from '@vue/shared' import { @@ -263,6 +263,7 @@ export function compileScript( let hasDefinePropsCall = false let hasDefineEmitCall = false let hasDefineExposeCall = false + let hasDefaultExportName = false let propsRuntimeDecl: Node | undefined let propsRuntimeDefaults: ObjectExpression | undefined let propsDestructureDecl: Node | undefined @@ -811,6 +812,25 @@ export function compileScript( } else if (node.type === 'ExportDefaultDeclaration') { // export default defaultExport = node + + // check if user has manually specified `name` option in export default + // if yes, skip infer later + let optionProperties + if (defaultExport.declaration.type === 'ObjectExpression') { + optionProperties = defaultExport.declaration.properties + } else if ( + defaultExport.declaration.type === 'CallExpression' && + defaultExport.declaration.arguments[0].type === 'ObjectExpression' + ) { + optionProperties = defaultExport.declaration.arguments[0].properties + } + hasDefaultExportName = !!optionProperties?.some( + s => + s.type === 'ObjectProperty' && + s.key.type === 'Identifier' && + s.key.name === 'name' + ) + // export default { ... } --> const __default__ = { ... } const start = node.start! + scriptStartOffset! const end = node.declaration.start! + scriptStartOffset! @@ -1364,6 +1384,12 @@ export function compileScript( // 11. finalize default export let runtimeOptions = `` + if (!hasDefaultExportName && filename && filename !== DEFAULT_FILENAME) { + const match = filename.match(/([^/\\]+)\.\w+$/) + if (match) { + runtimeOptions += `\n name: '${match[1]}',` + } + } if (hasInlinedSsrRenderFn) { runtimeOptions += `\n __ssrInlineRender: true,` } diff --git a/packages/compiler-sfc/src/parse.ts b/packages/compiler-sfc/src/parse.ts index ed44e5368..cc7873c29 100644 --- a/packages/compiler-sfc/src/parse.ts +++ b/packages/compiler-sfc/src/parse.ts @@ -13,6 +13,8 @@ import { parseCssVars } from './cssVars' import { createCache } from './cache' import { hmrShouldReload, ImportBinding } from './compileScript' +export const DEFAULT_FILENAME = 'anonymous.vue' + export interface SFCParseOptions { filename?: string sourceMap?: boolean @@ -95,7 +97,7 @@ export function parse( source: string, { sourceMap = true, - filename = 'anonymous.vue', + filename = DEFAULT_FILENAME, sourceRoot = '', pad = false, ignoreEmpty = true, From 7d7a2410e58d3ae59ca3fcf619f332699209fc96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=88=98=28liulinboyi=29?= <814921718@qq.com> Date: Tue, 10 May 2022 09:20:18 +0800 Subject: [PATCH 09/86] fix(compiler-sfc): remove the jsx from the babelParserPlugins when not match the case of adding jsx (#5846) fix #5845 --- packages/compiler-sfc/src/compileScript.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 7c84f29b3..7c16bcc8f 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -172,6 +172,12 @@ export function compileScript( const plugins: ParserPlugin[] = [] if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') { plugins.push('jsx') + } else { + // If don't match the case of adding jsx, should remove the jsx from the babelParserPlugins + if (options.babelParserPlugins) + options.babelParserPlugins = options.babelParserPlugins.filter( + n => n !== 'jsx' + ) } if (options.babelParserPlugins) plugins.push(...options.babelParserPlugins) if (isTS) plugins.push('typescript', 'decorators-legacy') From 0abcb2b80db1e9294b07838aa3eb2a19fe96b038 Mon Sep 17 00:00:00 2001 From: Damon Muma Date: Mon, 9 May 2022 21:30:50 -0400 Subject: [PATCH 10/86] chore: update reference to transformExpressions (#2682) [ci skip] --- packages/compiler-dom/src/transforms/stringifyStatic.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-dom/src/transforms/stringifyStatic.ts b/packages/compiler-dom/src/transforms/stringifyStatic.ts index e257e3254..d2d0b6fe0 100644 --- a/packages/compiler-dom/src/transforms/stringifyStatic.ts +++ b/packages/compiler-dom/src/transforms/stringifyStatic.ts @@ -330,7 +330,7 @@ function stringifyElement( // here, e.g. `{{ 1 }}` or `{{ 'foo' }}` // in addition, constant exps bail on presence of parens so you can't even // run JSFuck in here. But we mark it unsafe for security review purposes. -// (see compiler-core/src/transformExpressions) +// (see compiler-core/src/transforms/transformExpression) function evaluateConstant(exp: ExpressionNode): string { if (exp.type === NodeTypes.SIMPLE_EXPRESSION) { return new Function(`return ${exp.content}`)() From 7540a3ff1d893e377fd8bb1e5b96de0600ea4578 Mon Sep 17 00:00:00 2001 From: tarunama Date: Tue, 10 May 2022 10:37:00 +0900 Subject: [PATCH 11/86] chore(server renderer): readable warn message (#2890) --- packages/server-renderer/src/render.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/server-renderer/src/render.ts b/packages/server-renderer/src/render.ts index 3a08163f9..17b5609f1 100644 --- a/packages/server-renderer/src/render.ts +++ b/packages/server-renderer/src/render.ts @@ -188,11 +188,8 @@ function renderComponentSubTree( slotScopeId ) } else { - warn( - `Component ${ - comp.name ? `${comp.name} ` : `` - } is missing template or render function.` - ) + const componentName = comp.name || comp.__file || `` + warn(`Component ${componentName} is missing template or render function.`) push(``) } } From decad9df57d456676ca0c0425a5b498f56310986 Mon Sep 17 00:00:00 2001 From: edison Date: Tue, 10 May 2022 09:37:59 +0800 Subject: [PATCH 12/86] types(compiler-sfc): export SFCParseResult type (#2923) close #2921 --- packages/compiler-sfc/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/compiler-sfc/src/index.ts b/packages/compiler-sfc/src/index.ts index bf89c5de4..4df1b7f26 100644 --- a/packages/compiler-sfc/src/index.ts +++ b/packages/compiler-sfc/src/index.ts @@ -29,6 +29,7 @@ export { // Types export { SFCParseOptions, + SFCParseResult, SFCDescriptor, SFCBlock, SFCTemplateBlock, From 762a9e99ce43831c7b9da027de271aaa39f3924b Mon Sep 17 00:00:00 2001 From: edison Date: Tue, 10 May 2022 09:40:19 +0800 Subject: [PATCH 13/86] chore(runtime-core): use `getGlobalThis` when installing HMR API (#3217) --- packages/runtime-core/src/hmr.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/runtime-core/src/hmr.ts b/packages/runtime-core/src/hmr.ts index 3c3f5208b..1ea1dd01b 100644 --- a/packages/runtime-core/src/hmr.ts +++ b/packages/runtime-core/src/hmr.ts @@ -9,6 +9,7 @@ import { } from './component' import { queueJob, queuePostFlushCb } from './scheduler' import { extend, getGlobalThis } from '@vue/shared' +import { warn } from './warning' type HMRComponent = ComponentOptions | ClassComponent From 2a44225446d98781f935a5b07ee4f8ed6057fe85 Mon Sep 17 00:00:00 2001 From: edison Date: Tue, 10 May 2022 09:42:41 +0800 Subject: [PATCH 14/86] chore(runtime-core): Remove duplicate variable assignments (#3700) --- packages/runtime-core/src/renderer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 33fe7a23d..47a566e73 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -1288,7 +1288,6 @@ function baseCreateRenderer( } } else { // no update needed. just copy over properties - n2.component = n1.component n2.el = n1.el instance.vnode = n2 } From 29e454d4d143b7473ed7cb7e4292fa3cd9d7e3e8 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 09:50:12 +0800 Subject: [PATCH 15/86] chore: fix duplicate export --- packages/compiler-sfc/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/compiler-sfc/src/index.ts b/packages/compiler-sfc/src/index.ts index 4df1b7f26..b99aeafbb 100644 --- a/packages/compiler-sfc/src/index.ts +++ b/packages/compiler-sfc/src/index.ts @@ -34,8 +34,7 @@ export { SFCBlock, SFCTemplateBlock, SFCScriptBlock, - SFCStyleBlock, - SFCParseResult + SFCStyleBlock } from './parse' export { TemplateCompiler, From 16a0b232d7900c58d5f24a381f1844ced098ba2f Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 09:58:28 +0800 Subject: [PATCH 16/86] chore: remove unused import due to merge conflict resolve mistake --- packages/runtime-core/src/hmr.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/runtime-core/src/hmr.ts b/packages/runtime-core/src/hmr.ts index 1ea1dd01b..3c3f5208b 100644 --- a/packages/runtime-core/src/hmr.ts +++ b/packages/runtime-core/src/hmr.ts @@ -9,7 +9,6 @@ import { } from './component' import { queueJob, queuePostFlushCb } from './scheduler' import { extend, getGlobalThis } from '@vue/shared' -import { warn } from './warning' type HMRComponent = ComponentOptions | ClassComponent From e58277f6eaeaec84cf05b34126bec01b619a1b90 Mon Sep 17 00:00:00 2001 From: Julian Hundeloh Date: Tue, 10 May 2022 03:58:51 +0200 Subject: [PATCH 17/86] fix(runtime-dom): "el._assign is not a function" in compat mode (#4121) --- packages/runtime-dom/src/directives/vModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 6ca363a93..b3e10a2a1 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -18,7 +18,7 @@ import { type AssignerFn = (value: any) => void const getModelAssigner = (vnode: VNode): AssignerFn => { - const fn = vnode.props!['onUpdate:modelValue'] + const fn = vnode.props!['onUpdate:modelValue'] || (__COMPAT__ && vnode.props!['onModelCompat:input']) return isArray(fn) ? value => invokeArrayFns(fn, value) : fn } From 30c33af839ab33b3c45d5f9fca2a610e438cd14d Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 10:02:41 +0800 Subject: [PATCH 18/86] chore: use explicit type import to avoid Rollup warning --- packages/reactivity/src/reactive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/reactivity/src/reactive.ts b/packages/reactivity/src/reactive.ts index ce689012d..ac4505970 100644 --- a/packages/reactivity/src/reactive.ts +++ b/packages/reactivity/src/reactive.ts @@ -11,7 +11,7 @@ import { shallowCollectionHandlers, shallowReadonlyCollectionHandlers } from './collectionHandlers' -import { UnwrapRefSimple, Ref, RawSymbol } from './ref' +import type { UnwrapRefSimple, Ref, RawSymbol } from './ref' export const enum ReactiveFlags { SKIP = '__v_skip', From c355c4b78451708b04e17a7c50680dee507f0c40 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 10:04:56 +0800 Subject: [PATCH 19/86] fix(ssr): implement empty read() on node stream fix #3846 close #3867 --- packages/server-renderer/src/renderToStream.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server-renderer/src/renderToStream.ts b/packages/server-renderer/src/renderToStream.ts index 0644fb0a0..749fb54db 100644 --- a/packages/server-renderer/src/renderToStream.ts +++ b/packages/server-renderer/src/renderToStream.ts @@ -100,7 +100,7 @@ export function renderToNodeStream( context: SSRContext = {} ): Readable { const stream: Readable = __NODE_JS__ - ? new (require('stream').Readable)() + ? new (require('stream').Readable)({ read() {} }) : null if (!stream) { From 0aeb4bc9bf68c0006b496142bb5aeb3f06689b7c Mon Sep 17 00:00:00 2001 From: netcon Date: Tue, 10 May 2022 10:15:26 +0800 Subject: [PATCH 20/86] fix(shared): missed Symbol judge in looseEqual (#3553) --- packages/shared/__tests__/looseEqual.spec.ts | 12 ++++++++++++ packages/shared/src/looseEqual.ts | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/shared/__tests__/looseEqual.spec.ts b/packages/shared/__tests__/looseEqual.spec.ts index 75bb25058..24bd48c10 100644 --- a/packages/shared/__tests__/looseEqual.spec.ts +++ b/packages/shared/__tests__/looseEqual.spec.ts @@ -49,6 +49,18 @@ describe('utils/looseEqual', () => { expect(looseEqual(date1, date4)).toBe(false) }) + test('compares symbols correctly', () => { + const symbol1 = Symbol('a') + const symbol2 = Symbol('a') + const symbol3 = Symbol('b') + const notSymbol = 0 + + expect(looseEqual(symbol1, symbol1)).toBe(true) + expect(looseEqual(symbol1, symbol2)).toBe(false) + expect(looseEqual(symbol1, symbol3)).toBe(false) + expect(looseEqual(symbol1, notSymbol)).toBe(false) + }) + test('compares files correctly', () => { const date1 = new Date(2019, 1, 2, 3, 4, 5, 6) const date2 = new Date(2019, 1, 2, 3, 4, 5, 7) diff --git a/packages/shared/src/looseEqual.ts b/packages/shared/src/looseEqual.ts index 030f0338b..387150535 100644 --- a/packages/shared/src/looseEqual.ts +++ b/packages/shared/src/looseEqual.ts @@ -1,4 +1,4 @@ -import { isArray, isDate, isObject } from './' +import { isArray, isDate, isObject, isSymbol } from './' function looseCompareArrays(a: any[], b: any[]) { if (a.length !== b.length) return false @@ -16,6 +16,11 @@ export function looseEqual(a: any, b: any): boolean { if (aValidType || bValidType) { return aValidType && bValidType ? a.getTime() === b.getTime() : false } + aValidType = isSymbol(a) + bValidType = isSymbol(b) + if (aValidType || bValidType) { + return a === b + } aValidType = isArray(a) bValidType = isArray(b) if (aValidType || bValidType) { From 392ca5dd8807d16ea52225accbdabd0084250ddf Mon Sep 17 00:00:00 2001 From: huangcheng <1530844743@qq.com> Date: Tue, 10 May 2022 10:43:35 +0800 Subject: [PATCH 21/86] chore: fix eslint error (#5876) --- packages/runtime-core/src/devtools.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/devtools.ts b/packages/runtime-core/src/devtools.ts index 6bbd3db6e..36c5763dc 100644 --- a/packages/runtime-core/src/devtools.ts +++ b/packages/runtime-core/src/devtools.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-restricted-globals */ import { App } from './apiCreateApp' import { Fragment, Text, Comment, Static } from './vnode' import { ComponentInternalInstance } from './component' @@ -53,7 +54,6 @@ export function setDevtoolsHook(hook: DevtoolsHook, target: any) { // handle late devtools injection - only do this if we are in an actual // browser environment to avoid the timer handle stalling test runner exit // (#4815) - // eslint-disable-next-line no-restricted-globals typeof window !== 'undefined' && // some envs mock window but not fully window.HTMLElement && From 83aaa9b5469072f43314b11388e5985b77597acd Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 10:43:07 +0800 Subject: [PATCH 22/86] workflow: update eslint config to allow spread usage --- .eslintrc.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 4c667f902..71acd8dd8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,10 +16,11 @@ module.exports = { // most of the codebase are expected to be env agnostic 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals], // since we target ES2015 for baseline support, we need to forbid object - // rest spread usage (both assign and destructure) + // rest spread usage in destructure as it compiles into a verbose helper. + // TS now compiles assignment spread into Object.assign() calls so that + // is allowed. 'no-restricted-syntax': [ 'error', - 'ObjectExpression > SpreadElement', 'ObjectPattern > RestElement', 'AwaitExpression' ] From 1414f17490165d8d170afa651ee9866294d971f6 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 10:47:32 +0800 Subject: [PATCH 23/86] ci: run lint during ci --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e02bfc66..f4b51a822 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: - name: Run unit tests run: pnpm run test - test-dts: + lint-and-test-dts: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -46,6 +46,9 @@ jobs: - run: pnpm install + - name: Run eslint + run: pnpm run lint + - name: Run type declaration tests run: pnpm run test-dts From 9bcfcac993e25d53a47e875b1dbcf00e68253f4b Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 May 2022 10:47:45 +0800 Subject: [PATCH 24/86] chore: bump typescript deps --- package.json | 6 +-- pnpm-lock.yaml | 101 +++++++++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index 14f9ed5d5..633f97f66 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@types/jest": "^27.0.1", "@types/node": "^16.4.7", "@types/puppeteer": "^5.0.0", - "@typescript-eslint/parser": "^4.1.1", + "@typescript-eslint/parser": "^5.23.0", "@vue/reactivity": "workspace:*", "@vue/runtime-core": "workspace:*", "@vue/runtime-dom": "workspace:*", @@ -89,8 +89,8 @@ "serve": "^12.0.0", "todomvc-app-css": "^2.3.0", "ts-jest": "^27.0.5", - "tslib": "^2.3.1", - "typescript": "^4.2.2", + "tslib": "^2.4.0", + "typescript": "^4.6.4", "vite": "^2.9.0", "vue": "workspace:*", "yorkie": "^2.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee3e6b5c6..5ae771692 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: '@types/jest': ^27.0.1 '@types/node': ^16.4.7 '@types/puppeteer': ^5.0.0 - '@typescript-eslint/parser': ^4.1.1 + '@typescript-eslint/parser': ^5.23.0 '@vue/reactivity': workspace:* '@vue/runtime-core': workspace:* '@vue/runtime-dom': workspace:* @@ -46,8 +46,8 @@ importers: serve: ^12.0.0 todomvc-app-css: ^2.3.0 ts-jest: ^27.0.5 - tslib: ^2.3.1 - typescript: ^4.2.2 + tslib: ^2.4.0 + typescript: ^4.6.4 vite: ^2.9.0 vue: workspace:* yorkie: ^2.0.0 @@ -63,7 +63,7 @@ importers: '@types/jest': 27.0.3 '@types/node': 16.11.12 '@types/puppeteer': 5.4.4 - '@typescript-eslint/parser': 4.33.0_eslint@7.32.0+typescript@4.5.3 + '@typescript-eslint/parser': 5.23.0_eslint@7.32.0+typescript@4.6.4 '@vue/reactivity': link:packages/reactivity '@vue/runtime-core': link:packages/runtime-core '@vue/runtime-dom': link:packages/runtime-dom @@ -89,13 +89,13 @@ importers: rollup-plugin-node-globals: 1.4.0 rollup-plugin-polyfill-node: 0.6.2_rollup@2.38.5 rollup-plugin-terser: 7.0.2_rollup@2.38.5 - rollup-plugin-typescript2: 0.27.3_rollup@2.38.5+typescript@4.5.3 + rollup-plugin-typescript2: 0.27.3_rollup@2.38.5+typescript@4.6.4 semver: 7.3.5 serve: 12.0.1 todomvc-app-css: 2.4.1 - ts-jest: 27.1.1_044236483439d51e55e98a1311368c5f - tslib: 2.3.1 - typescript: 4.5.3 + ts-jest: 27.1.1_2afc78609cda1ff8b69f87fc5df4898b + tslib: 2.4.0 + typescript: 4.6.4 vite: 2.9.1 vue: link:packages/vue yorkie: 2.0.0 @@ -1207,66 +1207,66 @@ packages: dev: true optional: true - /@typescript-eslint/parser/4.33.0_eslint@7.32.0+typescript@4.5.3: - resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==} - engines: {node: ^10.12.0 || >=12.0.0} + /@typescript-eslint/parser/5.23.0_eslint@7.32.0+typescript@4.6.4: + resolution: {integrity: sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 4.33.0 - '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/typescript-estree': 4.33.0_typescript@4.5.3 + '@typescript-eslint/scope-manager': 5.23.0 + '@typescript-eslint/types': 5.23.0 + '@typescript-eslint/typescript-estree': 5.23.0_typescript@4.6.4 debug: 4.3.3 eslint: 7.32.0 - typescript: 4.5.3 + typescript: 4.6.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/4.33.0: - resolution: {integrity: sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + /@typescript-eslint/scope-manager/5.23.0: + resolution: {integrity: sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/visitor-keys': 4.33.0 + '@typescript-eslint/types': 5.23.0 + '@typescript-eslint/visitor-keys': 5.23.0 dev: true - /@typescript-eslint/types/4.33.0: - resolution: {integrity: sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + /@typescript-eslint/types/5.23.0: + resolution: {integrity: sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/4.33.0_typescript@4.5.3: - resolution: {integrity: sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==} - engines: {node: ^10.12.0 || >=12.0.0} + /@typescript-eslint/typescript-estree/5.23.0_typescript@4.6.4: + resolution: {integrity: sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/visitor-keys': 4.33.0 + '@typescript-eslint/types': 5.23.0 + '@typescript-eslint/visitor-keys': 5.23.0 debug: 4.3.3 globby: 11.0.4 is-glob: 4.0.3 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.5.3 - typescript: 4.5.3 + tsutils: 3.21.0_typescript@4.6.4 + typescript: 4.6.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/visitor-keys/4.33.0: - resolution: {integrity: sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==} - engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + /@typescript-eslint/visitor-keys/5.23.0: + resolution: {integrity: sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 4.33.0 - eslint-visitor-keys: 2.1.0 + '@typescript-eslint/types': 5.23.0 + eslint-visitor-keys: 3.3.0 dev: true /@vitejs/plugin-vue/1.10.2_vite@2.7.1: @@ -1367,7 +1367,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.1 + debug: 4.3.3 transitivePeerDependencies: - supports-color dev: true @@ -3018,6 +3018,11 @@ packages: engines: {node: '>=10'} dev: true + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /eslint/7.32.0: resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6170,7 +6175,7 @@ packages: - acorn dev: true - /rollup-plugin-typescript2/0.27.3_rollup@2.38.5+typescript@4.5.3: + /rollup-plugin-typescript2/0.27.3_rollup@2.38.5+typescript@4.6.4: resolution: {integrity: sha512-gmYPIFmALj9D3Ga1ZbTZAKTXq1JKlTQBtj299DXhqYz9cL3g/AQfUvbb2UhH+Nf++cCq941W2Mv7UcrcgLzJJg==} peerDependencies: rollup: '>=1.26.3' @@ -6182,7 +6187,7 @@ packages: resolve: 1.17.0 rollup: 2.38.5 tslib: 2.0.1 - typescript: 4.5.3 + typescript: 4.6.4 dev: true /rollup-pluginutils/2.8.2: @@ -6807,7 +6812,7 @@ packages: engines: {node: '>=8'} dev: true - /ts-jest/27.1.1_044236483439d51e55e98a1311368c5f: + /ts-jest/27.1.1_2afc78609cda1ff8b69f87fc5df4898b: resolution: {integrity: sha512-Ds0VkB+cB+8g2JUmP/GKWndeZcCKrbe6jzolGrVWdqVUFByY/2KDHqxJ7yBSon7hDB1TA4PXxjfZ+JjzJisvgA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -6838,7 +6843,7 @@ packages: lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.3.5 - typescript: 4.5.3 + typescript: 4.6.4 yargs-parser: 20.2.9 dev: true @@ -6854,18 +6859,18 @@ packages: resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==} dev: true - /tslib/2.3.1: - resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} + /tslib/2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: true - /tsutils/3.21.0_typescript@4.5.3: + /tsutils/3.21.0_typescript@4.6.4: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.5.3 + typescript: 4.6.4 dev: true /type-check/0.3.2: @@ -6932,6 +6937,12 @@ packages: hasBin: true dev: true + /typescript/4.6.4: + resolution: {integrity: sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /uglify-js/3.14.4: resolution: {integrity: sha512-AbiSR44J0GoCeV81+oxcy/jDOElO2Bx3d0MfQCUShq7JRXaM4KtQopZsq2vFv8bCq2yMaGrw1FgygUd03RyRDA==} engines: {node: '>=0.8.0'} From 908ffb4fd4b0a87b24a613b8bc2481507fc4fcb4 Mon Sep 17 00:00:00 2001 From: Leon Si Date: Mon, 9 May 2022 22:49:14 -0400 Subject: [PATCH 25/86] chore: typo (#5732) [ci skip] --- packages/vue/macros.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vue/macros.d.ts b/packages/vue/macros.d.ts index 41aefd77d..9df3f107c 100644 --- a/packages/vue/macros.d.ts +++ b/packages/vue/macros.d.ts @@ -55,7 +55,7 @@ type DestructureRefs = { } /** - * Vue ref transform macro for accessing underlying refs of reactive varaibles. + * Vue ref transform macro for accessing underlying refs of reactive variables. */ export declare function $$(arg: NormalObject): ToRawRefs export declare function $$(value: RefValue): Ref From 181872f744537b75a4cec8c4e49b2c7c4d4f81ff Mon Sep 17 00:00:00 2001 From: Khinenw Date: Tue, 10 May 2022 11:50:49 +0900 Subject: [PATCH 26/86] types(runtime-dom): fix typo in jsx type autosave (#5638) --- packages/runtime-dom/types/jsx.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-dom/types/jsx.d.ts b/packages/runtime-dom/types/jsx.d.ts index ab34e299d..9423a7556 100644 --- a/packages/runtime-dom/types/jsx.d.ts +++ b/packages/runtime-dom/types/jsx.d.ts @@ -276,7 +276,7 @@ export interface HTMLAttributes extends AriaAttributes, EventHandlers { // Non-standard Attributes autocapitalize?: string autocorrect?: string - autocave?: string + autosave?: string color?: string itemprop?: string itemscope?: Booleanish From 6042ab0f2f6141fff82ad3775c7de716d6d97d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=A3=E9=87=8C=E5=A5=BD=E8=84=8F=E4=B8=8D=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5?= <453491931@qq.com> Date: Tue, 10 May 2022 10:51:51 +0800 Subject: [PATCH 27/86] chore: type [ci skip] --- packages/compiler-core/__tests__/parse.spec.ts | 2 +- .../__tests__/transforms/transformElement.spec.ts | 2 +- .../__snapshots__/warnTransitionChildren.spec.ts.snap | 2 +- .../__tests__/transforms/warnTransitionChildren.spec.ts | 2 +- packages/compiler-sfc/__tests__/compileScript.spec.ts | 4 ++-- packages/compiler-sfc/src/cssVars.ts | 6 +++--- .../__snapshots__/reactivityTransform.spec.ts.snap | 4 ++-- .../__tests__/reactivityTransform.spec.ts | 2 +- packages/reactivity/__tests__/effectScope.spec.ts | 4 ++-- packages/reactivity/__tests__/readonly.spec.ts | 4 ++-- packages/reactivity/src/effectScope.ts | 2 +- packages/runtime-core/__tests__/components/Suspense.spec.ts | 4 ++-- packages/runtime-core/__tests__/errorHandling.spec.ts | 2 +- packages/runtime-core/__tests__/helpers/withMemo.spec.ts | 2 +- .../runtime-core/__tests__/rendererOptimizedMode.spec.ts | 2 +- packages/runtime-core/src/component.ts | 2 +- packages/runtime-core/src/componentOptions.ts | 4 ++-- packages/runtime-dom/__tests__/directives/vModel.spec.ts | 2 +- packages/runtime-dom/__tests__/patchProps.spec.ts | 2 +- packages/shared/__tests__/toDisplayString.spec.ts | 4 ++-- packages/vue-compat/README.md | 2 +- test-dts/component.test-d.ts | 4 ++-- 22 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index f1869739c..5d5e40566 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -2023,7 +2023,7 @@ foo isPreTag: tag => tag === 'pre' }) const elementAfterPre = ast.children[1] as ElementNode - // should not affect the and condense its whitepsace inside + // should not affect the and condense its whitespace inside expect((elementAfterPre.children[0] as TextNode).content).toBe(` foo bar`) }) diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index e7a95622d..a9edc9870 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -80,7 +80,7 @@ describe('compiler: element transform', () => { expect(root.components).toContain(`Foo`) }) - test('resolve implcitly self-referencing component', () => { + test('resolve implicitly self-referencing component', () => { const { root } = parseWithElementTransform(``, { filename: `/foo/bar/Example.vue?vue&type=template` }) diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/warnTransitionChildren.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/warnTransitionChildren.spec.ts.snap index 5787b08ff..2b39b25fa 100644 --- a/packages/compiler-dom/__tests__/transforms/__snapshots__/warnTransitionChildren.spec.ts.snap +++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/warnTransitionChildren.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`the v-if/else-if/else branchs in Transition should ignore comments 1`] = ` +exports[`the v-if/else-if/else branches in Transition should ignore comments 1`] = ` "const _Vue = Vue return function render(_ctx, _cache) { diff --git a/packages/compiler-dom/__tests__/transforms/warnTransitionChildren.spec.ts b/packages/compiler-dom/__tests__/transforms/warnTransitionChildren.spec.ts index 3cccdfffc..b037af8e6 100644 --- a/packages/compiler-dom/__tests__/transforms/warnTransitionChildren.spec.ts +++ b/packages/compiler-dom/__tests__/transforms/warnTransitionChildren.spec.ts @@ -139,7 +139,7 @@ describe('compiler warnings', () => { }) }) -test('the v-if/else-if/else branchs in Transition should ignore comments', () => { +test('the v-if/else-if/else branches in Transition should ignore comments', () => { expect( compile(` diff --git a/packages/compiler-sfc/__tests__/compileScript.spec.ts b/packages/compiler-sfc/__tests__/compileScript.spec.ts index 51ef6c9e7..f87a326c8 100644 --- a/packages/compiler-sfc/__tests__/compileScript.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript.spec.ts @@ -64,7 +64,7 @@ const bar = 1 `) // should generate working code assertCode(content) - // should anayze bindings + // should analyze bindings expect(bindings).toStrictEqual({ foo: BindingTypes.PROPS, bar: BindingTypes.SETUP_CONST, @@ -403,7 +403,7 @@ defineExpose({ foo: 123 }) assertCode(content) }) - // #4340 interpolations in tempalte strings + // #4340 interpolations in template strings test('js template string interpolations', () => { const { content } = compile(` + + `) + expect(content).toMatch(`return { a, b, Baz }`) + assertCode(content) + }) }) describe('inlineTemplate mode', () => { diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 9c9c7ffbf..509934d6d 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -12,7 +12,12 @@ import { walkIdentifiers } from '@vue/compiler-dom' import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse' -import { parse as _parse, ParserOptions, ParserPlugin } from '@babel/parser' +import { + parse as _parse, + parseExpression, + ParserOptions, + ParserPlugin +} from '@babel/parser' import { camelize, capitalize, generateCodeFrame, makeMap } from '@vue/shared' import { Node, @@ -348,14 +353,23 @@ export function compileScript( local: string, imported: string | false, isType: boolean, - isFromSetup: boolean + isFromSetup: boolean, + needTemplateUsageCheck: boolean ) { if (source === 'vue' && imported) { userImportAlias[imported] = local } - let isUsedInTemplate = true - if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) { + // template usage check is only needed in non-inline mode, so we can skip + // the work if inlineTemplate is true. + let isUsedInTemplate = needTemplateUsageCheck + if ( + needTemplateUsageCheck && + isTS && + sfc.template && + !sfc.template.src && + !sfc.template.lang + ) { isUsedInTemplate = isImportUsed(local, sfc) } @@ -813,7 +827,8 @@ export function compileScript( node.importKind === 'type' || (specifier.type === 'ImportSpecifier' && specifier.importKind === 'type'), - false + false, + !options.inlineTemplate ) } } else if (node.type === 'ExportDefaultDeclaration') { @@ -1027,7 +1042,8 @@ export function compileScript( node.importKind === 'type' || (specifier.type === 'ImportSpecifier' && specifier.importKind === 'type'), - true + true, + !options.inlineTemplate ) } } @@ -2051,14 +2067,14 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { code += `,v${capitalize(camelize(prop.name))}` } if (prop.exp) { - code += `,${stripStrings( + code += `,${processExp( (prop.exp as SimpleExpressionNode).content )}` } } } } else if (node.type === NodeTypes.INTERPOLATION) { - code += `,${stripStrings( + code += `,${processExp( (node.content as SimpleExpressionNode).content )}` } @@ -2071,6 +2087,19 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) { return code } +function processExp(exp: string) { + if (/ as \w|<.*>/.test(exp)) { + let ret = '' + // has potential type cast or generic arguments that uses types + const ast = parseExpression(exp, { plugins: ['typescript'] }) + walkIdentifiers(ast, node => { + ret += `,` + node.name + }) + return ret + } + return stripStrings(exp) +} + function stripStrings(exp: string) { return exp .replace(/'[^']*'|"[^"]*"/g, '') From 8c51c6514f99b4c70183f4c1a0eaabd482f88d5b Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 12 May 2022 18:39:17 +0800 Subject: [PATCH 65/86] fix(v-model): exclude range from lazy guard logic fix #5875 --- packages/runtime-dom/src/directives/vModel.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index b3e10a2a1..3d05e9fa4 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -18,7 +18,9 @@ import { type AssignerFn = (value: any) => void const getModelAssigner = (vnode: VNode): AssignerFn => { - const fn = vnode.props!['onUpdate:modelValue'] || (__COMPAT__ && vnode.props!['onModelCompat:input']) + const fn = + vnode.props!['onUpdate:modelValue'] || + (__COMPAT__ && vnode.props!['onModelCompat:input']) return isArray(fn) ? value => invokeArrayFns(fn, value) : fn } @@ -78,7 +80,7 @@ export const vModelText: ModelDirective< el._assign = getModelAssigner(vnode) // avoid clearing unresolved text. #2302 if ((el as any).composing) return - if (document.activeElement === el) { + if (document.activeElement === el && el.type !== 'range') { if (lazy) { return } From 8a123ac34fd30fc36ac9e0c252dd345d6d7c7f50 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 12 May 2022 18:56:54 +0800 Subject: [PATCH 66/86] fix(compiler-sfc): fix treeshaking of namespace import when used in template fix #5209 --- .../__tests__/__snapshots__/compileScript.spec.ts.snap | 4 +++- packages/compiler-sfc/__tests__/compileScript.spec.ts | 4 ++++ packages/compiler-sfc/src/compileScript.ts | 9 +++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap index 757b15341..55ed14aa7 100644 --- a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap @@ -777,6 +777,7 @@ exports[`SFC compile + + `) + expect(content).toMatch(`x = __props["foo.bar"]`) + expect(content).toMatch(`toDisplayString(__props["foo.bar"])`) + assertCode(content) + expect(bindings).toStrictEqual({ + x: BindingTypes.SETUP_LET, + 'foo.bar': BindingTypes.PROPS, + fooBar: BindingTypes.PROPS_ALIASED, + __propsAliases: { + fooBar: 'foo.bar' + } + }) + }) + test('rest spread', () => { const { content, bindings } = compile(` + + `) + assertCode(content) + }) + describe('