chore: Merge branch 'main' into minor

This commit is contained in:
Evan You 2024-06-14 18:15:20 +02:00
commit 524e660e35
No known key found for this signature in database
GPG Key ID: B9D421896CA450FB
10 changed files with 81 additions and 32 deletions

View File

@ -1,3 +1,17 @@
## [3.4.29](https://github.com/vuejs/core/compare/v3.4.28...v3.4.29) (2024-06-14)
### Bug Fixes
* **build:** fix accidental inclusion of runtime-core in server-renderer cjs build ([11cc12b](https://github.com/vuejs/core/commit/11cc12b915edfe0e4d3175e57464f73bc2c1cb04)), closes [#11137](https://github.com/vuejs/core/issues/11137)
* **compiler-sfc:** fix missing scope for extends error message ([4ec387b](https://github.com/vuejs/core/commit/4ec387b100985b008cdcc4cd883a5b6328c05766))
* **compiler-sfc:** fix parsing of mts, d.mts, and mtsx files ([a476692](https://github.com/vuejs/core/commit/a476692ed2d7308f2742d8ff3554cf97a392b0b7))
* **compiler-sfc:** support [@vue-ignore](https://github.com/vue-ignore) comment on more type sources ([a23e99b](https://github.com/vuejs/core/commit/a23e99bedf1d65841d162951f10ce35b907a5680))
* **custom-element:** support same direct setup function signature in defineCustomElement ([7c8b126](https://github.com/vuejs/core/commit/7c8b12620aad4969b8dc4944d4fc486d16c3033c)), closes [#11116](https://github.com/vuejs/core/issues/11116)
* **reactivity:** avoid infinite loop when render access a side effect computed ([#11135](https://github.com/vuejs/core/issues/11135)) ([8296e19](https://github.com/vuejs/core/commit/8296e19855e369a7826f5ea26540a6da01dc7093)), closes [#11121](https://github.com/vuejs/core/issues/11121)
## [3.4.28](https://github.com/vuejs/core/compare/v3.4.27...v3.4.28) (2024-06-14) ## [3.4.28](https://github.com/vuejs/core/compare/v3.4.27...v3.4.28) (2024-06-14)

View File

@ -137,6 +137,18 @@ describe('resolveType', () => {
}) })
}) })
test('intersection type with ignore', () => {
expect(
resolve(`
type Foo = { foo: number }
type Bar = { bar: string }
defineProps<Foo & /* @vue-ignore */ Bar>()
`).props,
).toStrictEqual({
foo: ['Number'],
})
})
// #7553 // #7553
test('union type', () => { test('union type', () => {
expect( expect(

View File

@ -175,14 +175,14 @@ export function resolveParserPlugins(
) { ) {
plugins.push('importAttributes') plugins.push('importAttributes')
} }
if (lang === 'jsx' || lang === 'tsx') { if (lang === 'jsx' || lang === 'tsx' || lang === 'mtsx') {
plugins.push('jsx') plugins.push('jsx')
} else if (userPlugins) { } else if (userPlugins) {
// If don't match the case of adding jsx // If don't match the case of adding jsx
// should remove the jsx from user options // should remove the jsx from user options
userPlugins = userPlugins.filter(p => p !== 'jsx') userPlugins = userPlugins.filter(p => p !== 'jsx')
} }
if (lang === 'ts' || lang === 'tsx') { if (lang === 'ts' || lang === 'mts' || lang === 'tsx' || lang === 'mtsx') {
plugins.push(['typescript', { dts }], 'explicitResourceManagement') plugins.push(['typescript', { dts }], 'explicitResourceManagement')
if (!userPlugins || !userPlugins.includes('decorators')) { if (!userPlugins || !userPlugins.includes('decorators')) {
plugins.push('decorators-legacy') plugins.push('decorators-legacy')

View File

@ -165,6 +165,12 @@ function innerResolveTypeElements(
scope: TypeScope, scope: TypeScope,
typeParameters?: Record<string, Node>, typeParameters?: Record<string, Node>,
): ResolvedElements { ): ResolvedElements {
if (
node.leadingComments &&
node.leadingComments.some(c => c.value.includes('@vue-ignore'))
) {
return { props: {} }
}
switch (node.type) { switch (node.type) {
case 'TSTypeLiteral': case 'TSTypeLiteral':
return typeElementsToMap(ctx, node.members, scope, typeParameters) return typeElementsToMap(ctx, node.members, scope, typeParameters)
@ -414,12 +420,6 @@ function resolveInterfaceMembers(
) )
if (node.extends) { if (node.extends) {
for (const ext of node.extends) { for (const ext of node.extends) {
if (
ext.leadingComments &&
ext.leadingComments.some(c => c.value.includes('@vue-ignore'))
) {
continue
}
try { try {
const { props, calls } = resolveTypeElements(ctx, ext, scope) const { props, calls } = resolveTypeElements(ctx, ext, scope)
for (const key in props) { for (const key in props) {
@ -439,6 +439,7 @@ function resolveInterfaceMembers(
`Note: both in 3.2 or with the ignore, the properties in the base ` + `Note: both in 3.2 or with the ignore, the properties in the base ` +
`type are treated as fallthrough attrs at runtime.`, `type are treated as fallthrough attrs at runtime.`,
ext, ext,
scope,
) )
} }
} }
@ -1138,12 +1139,12 @@ function parseFile(
parserPlugins?: SFCScriptCompileOptions['babelParserPlugins'], parserPlugins?: SFCScriptCompileOptions['babelParserPlugins'],
): Statement[] { ): Statement[] {
const ext = extname(filename) const ext = extname(filename)
if (ext === '.ts' || ext === '.tsx') { if (ext === '.ts' || ext === '.mts' || ext === '.tsx' || ext === '.mtsx') {
return babelParse(content, { return babelParse(content, {
plugins: resolveParserPlugins( plugins: resolveParserPlugins(
ext.slice(1), ext.slice(1),
parserPlugins, parserPlugins,
filename.endsWith('.d.ts'), /\.d\.m?ts$/.test(filename),
), ),
sourceType: 'module', sourceType: 'module',
}).program.body }).program.body

View File

@ -22,11 +22,3 @@ export enum ReactiveFlags {
RAW = '__v_raw', RAW = '__v_raw',
IS_REF = '__v_isRef', IS_REF = '__v_isRef',
} }
export enum DirtyLevels {
NotDirty = 0,
QueryingDirty = 1,
MaybeDirty_ComputedSideEffect = 2,
MaybeDirty = 3,
Dirty = 4,
}

View File

@ -342,6 +342,23 @@ describe('defineCustomElement', () => {
expect(el.maxAge).toBe(50) expect(el.maxAge).toBe(50)
expect(el.shadowRoot.innerHTML).toBe('max age: 50/type: number') expect(el.shadowRoot.innerHTML).toBe('max age: 50/type: number')
}) })
test('support direct setup function syntax with extra options', () => {
const E = defineCustomElement(
props => {
return () => props.text
},
{
props: {
text: String,
},
},
)
customElements.define('my-el-setup-with-props', E)
container.innerHTML = `<my-el-setup-with-props text="hello"></my-el-setup-with-props>`
const e = container.childNodes[0] as VueElement
expect(e.shadowRoot!.innerHTML).toBe('hello')
})
}) })
describe('attrs', () => { describe('attrs', () => {

View File

@ -38,10 +38,16 @@ export type VueElementConstructor<P = {}> = {
// overload 1: direct setup function // overload 1: direct setup function
export function defineCustomElement<Props, RawBindings = object>( export function defineCustomElement<Props, RawBindings = object>(
setup: ( setup: (props: Props, ctx: SetupContext) => RawBindings | RenderFunction,
props: Readonly<Props>, options?: Pick<ComponentOptions, 'name' | 'inheritAttrs' | 'emits'> & {
ctx: SetupContext, props?: (keyof Props)[]
) => RawBindings | RenderFunction, },
): VueElementConstructor<Props>
export function defineCustomElement<Props, RawBindings = object>(
setup: (props: Props, ctx: SetupContext) => RawBindings | RenderFunction,
options?: Pick<ComponentOptions, 'name' | 'inheritAttrs' | 'emits'> & {
props?: ComponentObjectPropsOptions<Props>
},
): VueElementConstructor<Props> ): VueElementConstructor<Props>
// overload 2: defineCustomElement with options object, infer props from options // overload 2: defineCustomElement with options object, infer props from options
@ -127,9 +133,13 @@ export function defineCustomElement<P>(
/*! #__NO_SIDE_EFFECTS__ */ /*! #__NO_SIDE_EFFECTS__ */
export function defineCustomElement( export function defineCustomElement(
options: any, options: any,
extraOptions?: ComponentOptions,
/**
* @internal
*/
hydrate?: RootHydrateFunction, hydrate?: RootHydrateFunction,
): VueElementConstructor { ): VueElementConstructor {
const Comp = defineComponent(options) as any const Comp = defineComponent(options, extraOptions) as any
class VueCustomElement extends VueElement { class VueCustomElement extends VueElement {
static def = Comp static def = Comp
constructor(initialProps?: Record<string, any>) { constructor(initialProps?: Record<string, any>) {
@ -141,9 +151,12 @@ export function defineCustomElement(
} }
/*! #__NO_SIDE_EFFECTS__ */ /*! #__NO_SIDE_EFFECTS__ */
export const defineSSRCustomElement = ((options: any) => { export const defineSSRCustomElement = ((
options: any,
extraOptions?: ComponentOptions,
) => {
// @ts-expect-error // @ts-expect-error
return defineCustomElement(options, hydrate) return defineCustomElement(options, extraOptions, hydrate)
}) as typeof defineCustomElement }) as typeof defineCustomElement
const BaseClass = ( const BaseClass = (

View File

@ -1,8 +1,4 @@
import { import { type ComponentPublicInstance, type Directive, ssrUtils } from 'vue'
type ComponentPublicInstance,
type Directive,
ssrUtils,
} from '@vue/runtime-core'
export function ssrGetDirectiveProps( export function ssrGetDirectiveProps(
instance: ComponentPublicInstance, instance: ComponentPublicInstance,

View File

@ -352,8 +352,11 @@ async function getCIResult() {
`https://api.github.com/repos/vuejs/core/actions/runs?head_sha=${sha}` + `https://api.github.com/repos/vuejs/core/actions/runs?head_sha=${sha}` +
`&status=success&exclude_pull_requests=true`, `&status=success&exclude_pull_requests=true`,
) )
/** @type {{ workflow_runs: ({ name: string, conclusion: string })[] }} */
const data = await res.json() const data = await res.json()
return data.workflow_runs.length > 0 return data.workflow_runs.some(({ name, conclusion }) => {
return name === 'ci' && conclusion === 'success'
})
} catch { } catch {
console.error('Failed to get CI status for current commit.') console.error('Failed to get CI status for current commit.')
return false return false

View File

@ -36,5 +36,6 @@
"packages/vue/jsx-runtime", "packages/vue/jsx-runtime",
"scripts/*", "scripts/*",
"rollup.*.js" "rollup.*.js"
] ],
"exclude": ["packages/sfc-playground/src/vue-dev-proxy*"]
} }