diff --git a/packages/vike-vue/package.json b/packages/vike-vue/package.json index 6f7ab33b..64738403 100644 --- a/packages/vike-vue/package.json +++ b/packages/vike-vue/package.json @@ -22,8 +22,8 @@ }, "./clientOnly": "./dist/helpers/clientOnly.js", "./types": { - "default": "./dist/hooks/types.js", - "types": "./dist/hooks/types.d.ts" + "default": "./dist/types/public.js", + "types": "./dist/types/public.d.ts" } }, "scripts": { @@ -55,7 +55,7 @@ "./dist/+config.d.ts" ], "types": [ - "./dist/hooks/types.d.ts" + "./dist/types/public.d.ts" ], "usePageContext": [ "./dist/hooks/usePageContext.d.ts" diff --git a/packages/vike-vue/src/+config.ts b/packages/vike-vue/src/+config.ts index bdd612c2..a9311a0d 100644 --- a/packages/vike-vue/src/+config.ts +++ b/packages/vike-vue/src/+config.ts @@ -1,54 +1,23 @@ +export { config } + +import type { Config, ImportString, PageContextServer, PageContext, PageContextClient } from 'vike/types' import type { OnCreateAppSync, OnCreateAppAsync, + OnBeforeRenderHtmlSync, + OnBeforeRenderHtmlAsync, OnAfterRenderHtmlSync, OnAfterRenderHtmlAsync, OnBeforeRenderClientSync, OnBeforeRenderClientAsync, - BodyInjectHtml, - OnBeforeRenderHtmlSync, - OnBeforeRenderHtmlAsync, -} from './hooks/types' - -import type { - Config, - ConfigEffect, - ImportString, - PageContextServer, - // Rename it to `PageContext_` to be able to reference it from within `namespace Vike` - // - https://stackoverflow.com/questions/46559021/typescript-use-of-global-type-inside-namespace-with-same-type - // - https://github.com/Microsoft/TypeScript/issues/983 - PageContext as PageContext_, - PageContextClient, -} from 'vike/types' - +} from './types/VikeHooks' import type { Component } from './types/PageContext' import type { TagAttributes } from './utils/getTagAttributesString' import type { Viewport } from './renderer/onRenderHtml' +import './utils/tsx-workaround.js' +import { ssrEffect } from './renderer/ssrEffect.js' -// Depending on the value of `config.meta.ssr`, set other config options' `env` -// accordingly. -// See https://vike.dev/meta#:~:text=Modifying%20the%20environment%20of%20existing%20hooks -const toggleSsrRelatedConfig: ConfigEffect = ({ configDefinedAt, configValue }) => { - if (typeof configValue !== 'boolean') { - throw new Error(`${configDefinedAt} should be a boolean`) - } - - return { - meta: { - // When the SSR flag is false, we want to render the page only in the - // browser. We achieve this by then making the `Page` implementation - // accessible only in the client's renderer. - Page: { - env: configValue - ? { server: true, client: true } // default - : { client: true }, - }, - }, - } -} - -export default { +const config = { name: 'vike-vue', require: { vike: '>=0.4.183', @@ -98,7 +67,7 @@ export default { }, ssr: { env: { config: true }, - effect: toggleSsrRelatedConfig, + effect: ssrEffect, }, stream: { env: { server: true }, @@ -358,24 +327,9 @@ declare global { } } -// This is a workaround for -// * https://github.com/vuejs/core/issues/8303 -// * https://github.com/esbuild-kit/tsx/issues/113 -// Without this, when running vike-vue with tsx (for example when scaffolding a -// Vue+Express project with Bati), querying the server will fail with the -// following error: -// [vike][request(1)] HTTP request: / -// [vite][request(1)] __name is not defined -// [vite][request(1)] __name is not defined -// [vite][request(1)] __name is not defined -// [vite][request(1)] Error when evaluating SSR module virtual:vike:importPageCode:server:/pages/index: failed to import "/pages/index/+Page.vue" -// |- ReferenceError: __name is not defined -const globalName = (target: Object, value: string) => - Object.defineProperty(target, 'name', { - value, - configurable: true, - }) -declare global { - var __name: typeof globalName -} -globalThis.__name = globalName +// Be able to reference it from within `namespace Vike` +// - https://stackoverflow.com/questions/46559021/typescript-use-of-global-type-inside-namespace-with-same-type +// - https://github.com/Microsoft/TypeScript/issues/983 +type PageContext_ = PageContext + +type BodyInjectHtml = string | ((pageContext: PageContext) => string) diff --git a/packages/vike-vue/src/renderer/ssrEffect.ts b/packages/vike-vue/src/renderer/ssrEffect.ts new file mode 100644 index 00000000..410799bd --- /dev/null +++ b/packages/vike-vue/src/renderer/ssrEffect.ts @@ -0,0 +1,20 @@ +export { ssrEffect } + +import type { ConfigEffect } from 'vike/types' + +function ssrEffect({ configDefinedAt, configValue }: Parameters[0]): ReturnType { + if (typeof configValue !== 'boolean') throw new Error(`${configDefinedAt} should be a boolean`) + const env = { + // Always load on the client-side. + client: true, + // When the SSR flag is false, we want to render the page only on the client-side. + // We achieve this by loading `Page` only on the client-side: when onRenderHtml() + // gets a `Page` value that is undefined it skip server-side rendering. + server: configValue !== false, + } + return { + meta: { + Page: { env }, + }, + } +} diff --git a/packages/vike-vue/src/hooks/types.ts b/packages/vike-vue/src/types/VikeHooks.ts similarity index 94% rename from packages/vike-vue/src/hooks/types.ts rename to packages/vike-vue/src/types/VikeHooks.ts index 018ae421..1ddd7ed8 100644 --- a/packages/vike-vue/src/hooks/types.ts +++ b/packages/vike-vue/src/types/VikeHooks.ts @@ -7,10 +7,10 @@ export type { OnAfterRenderHtmlAsync, OnBeforeRenderClientSync, OnBeforeRenderClientAsync, - BodyInjectHtml, } import type { PageContext, PageContextClient, PageContextServer } from 'vike/types' + type PageContextWithApp = PageContext & { app: NonNullable } // Purposeful code duplication for improving QuickInfo IntelliSense @@ -73,8 +73,3 @@ type OnBeforeRenderClientSync = (pageContext: PageContextClient) => void * Typically used for hydrating state management libraries. */ type OnBeforeRenderClientAsync = (pageContext: PageContextClient) => Promise - -/** - * Injected HTML at the start / end of the body. - */ -type BodyInjectHtml = string | ((pageContext: PageContext) => string) diff --git a/packages/vike-vue/src/types/index.ts b/packages/vike-vue/src/types/index.ts deleted file mode 100644 index f69328a7..00000000 --- a/packages/vike-vue/src/types/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './PageContext.js' -import './Config.js' diff --git a/packages/vike-vue/src/types/public.ts b/packages/vike-vue/src/types/public.ts new file mode 100644 index 00000000..5406fdd0 --- /dev/null +++ b/packages/vike-vue/src/types/public.ts @@ -0,0 +1 @@ +export type * from './VikeHooks' diff --git a/packages/vike-vue/src/utils/tsx-workaround.ts b/packages/vike-vue/src/utils/tsx-workaround.ts new file mode 100644 index 00000000..178d6ce2 --- /dev/null +++ b/packages/vike-vue/src/utils/tsx-workaround.ts @@ -0,0 +1,18 @@ +// This is a workaround for +// * https://github.com/esbuild-kit/tsx/issues/113 +// * https://github.com/vuejs/core/issues/8303 +// Without this, when running vike-vue with tsx (for example when scaffolding a +// Vue+Express project with Bati), querying the server will fail with the +// following error: +// [vike][request(1)] HTTP request: / +// [vite][request(1)] __name is not defined +// [vite][request(1)] __name is not defined +// [vite][request(1)] __name is not defined +// [vite][request(1)] Error when evaluating SSR module virtual:vike:importPageCode:server:/pages/index: failed to import "/pages/index/+Page.vue" +// |- ReferenceError: __name is not defined +const globalName = (target: Object, value: string) => + Object.defineProperty(target, 'name', { + value, + configurable: true, + }) +;(globalThis as any).__name = globalName