diff --git a/docs/api/index.md b/docs/api/index.md index 47d5b7c33..c5349f360 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -67,7 +67,7 @@ If you find yourself having to set common App configuration for many of your tes ### attachTo -Specify the node to mount the component on. +Specify the node to mount the component on. This is not available when using `renderToString`. **Signature:** diff --git a/src/renderToString.ts b/src/renderToString.ts index c8aaa335f..9d2250852 100644 --- a/src/renderToString.ts +++ b/src/renderToString.ts @@ -18,7 +18,7 @@ import { Prop } from 'vue' -import { MountingOptions } from './types' +import { RenderMountingOptions } from './types' import { createInstance } from './createInstance' // NOTE this should come from `vue` @@ -31,7 +31,7 @@ type ComponentMountingOptions = T extends DefineComponent< any, any > - ? MountingOptions< + ? RenderMountingOptions< Partial> & Omit< Readonly> & PublicProps, @@ -40,7 +40,7 @@ type ComponentMountingOptions = T extends DefineComponent< D > & Record - : MountingOptions + : RenderMountingOptions // Class component (without vue-class-component) - no props export function renderToString( @@ -48,7 +48,7 @@ export function renderToString( new (...args: any[]): V __vccOpts: any }, - options?: MountingOptions & Record + options?: RenderMountingOptions & Record ): Promise // Class component (without vue-class-component) - props @@ -58,7 +58,7 @@ export function renderToString( __vccOpts: any defaultProps?: Record> | string[] }, - options?: MountingOptions

& Record + options?: RenderMountingOptions

& Record ): Promise // Class component - no props @@ -67,7 +67,7 @@ export function renderToString( new (...args: any[]): V registerHooks(keys: string[]): void }, - options?: MountingOptions & Record + options?: RenderMountingOptions & Record ): Promise // Class component - props @@ -77,13 +77,13 @@ export function renderToString( props(Props: P): any registerHooks(keys: string[]): void }, - options?: MountingOptions

& Record + options?: RenderMountingOptions

& Record ): Promise // Functional component with emits export function renderToString( originalComponent: FunctionalComponent, - options?: MountingOptions & Record + options?: RenderMountingOptions & Record ): Promise // Component declared with defineComponent @@ -115,7 +115,7 @@ export function renderToString< Props, Defaults >, - options?: MountingOptions< + options?: RenderMountingOptions< Partial & Omit, D > & @@ -150,7 +150,7 @@ export function renderToString< Extends, EE >, - options?: MountingOptions + options?: RenderMountingOptions ): Promise // Component declared with { props: [] } @@ -180,7 +180,7 @@ export function renderToString< EE, Props >, - options?: MountingOptions + options?: RenderMountingOptions ): Promise // Component declared with { props: { ... } } @@ -208,10 +208,17 @@ export function renderToString< Extends, EE >, - options?: MountingOptions & PublicProps, D> + options?: RenderMountingOptions< + ExtractPropTypes & PublicProps, + D + > ): Promise export function renderToString(component: any, options?: any): Promise { + if (options?.attachTo) { + console.warn('attachTo option is not available for renderToString') + } + const { app } = createInstance(component, options) return baseRenderToString(app) } diff --git a/src/types.ts b/src/types.ts index f792c35da..9a845af57 100644 --- a/src/types.ts +++ b/src/types.ts @@ -41,7 +41,7 @@ type RawProps = VNodeProps & { [Symbol.iterator]?: never } & Record -export interface MountingOptions { +interface BaseMountingOptions { /** * Overrides component's default data. Must be a function. * @see https://test-utils.vuejs.org/api/#data @@ -72,18 +72,36 @@ export interface MountingOptions { * Provides global mounting options to the component. */ global?: GlobalMountOptions + /** + * Automatically stub out all the child components. + * @default false + * @see https://test-utils.vuejs.org/api/#slots + */ + shallow?: boolean +} + +/** + * Mounting options for `mount` and `shallowMount` + */ +export interface MountingOptions + extends BaseMountingOptions { /** * Specify where to mount the component. * Can be a valid CSS selector, or an Element connected to the document. * @see https://test-utils.vuejs.org/api/#attachto */ attachTo?: HTMLElement | string +} + +/** + * Mounting options for `renderToString` + */ +export interface RenderMountingOptions + extends BaseMountingOptions { /** - * Automatically stub out all the child components. - * @default false - * @see https://test-utils.vuejs.org/api/#slots + * Attach to is not available in SSR mode */ - shallow?: boolean + attachTo?: never } export type Stub = boolean | Component | Directive diff --git a/test-dts/renderToString.d-test.ts b/test-dts/renderToString.d-test.ts index 02c8a3361..12c950ec8 100644 --- a/test-dts/renderToString.d-test.ts +++ b/test-dts/renderToString.d-test.ts @@ -105,3 +105,11 @@ class ClassComponent extends Vue { } } expectType>(renderToString(ClassComponent)) + +// No `attachTo` mounting option +expectError( + renderToString(AppWithProps, { + // @ts-expect-error should not have attachTo mounting option + attachTo: 'body' + }) +) diff --git a/tests/renderToString.spec.ts b/tests/renderToString.spec.ts index 02724331b..7a8166c73 100644 --- a/tests/renderToString.spec.ts +++ b/tests/renderToString.spec.ts @@ -3,7 +3,7 @@ * @vitest-environment node */ -import { describe, it, expect } from 'vitest' +import { describe, it, expect, vi } from 'vitest' import { defineComponent, onMounted, onServerPrefetch, ref } from 'vue' import { renderToString } from '../src' @@ -61,4 +61,26 @@ describe('renderToString', () => { expect(contents).toBe('

onServerPrefetch
') }) + + it('returns print warning if `attachTo` option is used', async () => { + const spy = vi.spyOn(console, 'warn').mockReturnValue() + + const Component = defineComponent({ + template: '
foo
' + }) + + expect( + // @ts-expect-error `attachTo` property is not allowed + await renderToString(Component, { + attachTo: 'body' + }) + ).toBe('
foo
') + + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toHaveBeenCalledWith( + 'attachTo option is not available for renderToString' + ) + + spy.mockRestore() + }) })