From 49634d355d54fd9faceba1d8b756d69ae7747746 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Wed, 8 Jan 2025 16:32:43 +1100 Subject: [PATCH] perf!: client / server subpaths (#448) * perf!: client / server subpaths * chore: keep `createHeadCore` export, add `unhead/legacy` --- examples/vite-ssr-react/src/entry-server.jsx | 2 +- packages/addons/test/infer-seo-meta.test.ts | 2 +- packages/dom/README.md | 12 ----- packages/dom/export-size-report.json | 36 ------------- packages/dom/package.json | 10 ++-- packages/dom/src/index.ts | 4 +- packages/schema-org/test/e2e/vue.test.ts | 3 +- packages/schema-org/test/index.ts | 3 +- packages/schema-org/test/ssr/xss.test.ts | 3 +- packages/ssr/README.md | 12 ----- packages/ssr/export-size-report.json | 50 ------------------- packages/ssr/package.json | 8 ++- packages/ssr/src/index.ts | 4 +- packages/unhead/build.config.ts | 3 ++ packages/unhead/client.d.ts | 1 + packages/unhead/legacy.d.ts | 1 + packages/unhead/package.json | 25 +++++++++- packages/unhead/server.d.ts | 1 + packages/unhead/src/client/createHead.ts | 18 +++++++ .../src => unhead/src/client}/debounced.ts | 0 .../src => unhead/src/client}/domPlugin.ts | 2 +- packages/unhead/src/client/index.ts | 4 ++ .../src/client}/renderDOMHead.ts | 0 packages/unhead/src/createHead.ts | 23 +-------- packages/unhead/src/index.ts | 13 +---- packages/unhead/src/legacy.ts | 29 +++++++++++ packages/unhead/src/server/createHead.ts | 10 ++++ packages/unhead/src/server/index.ts | 4 ++ .../src/{ => server}/plugins/payload.ts | 0 .../src/server}/renderSSRHead.ts | 0 .../src => unhead/src/server}/util/index.ts | 0 .../src/server}/util/propsToString.ts | 0 .../src/server}/util/ssrRenderTags.ts | 0 .../src/server}/util/tagToString.ts | 0 packages/vue/build.config.ts | 2 + packages/vue/client.d.ts | 1 + packages/vue/package.json | 20 +++++++- packages/vue/server.d.ts | 1 + packages/vue/src/client/index.ts | 14 ++++++ packages/vue/src/createHead.ts | 24 +-------- packages/vue/src/index.ts | 6 +-- packages/vue/src/server/index.ts | 12 +++++ packages/vue/test/dom/innerContent.test.ts | 2 +- packages/vue/test/dom/keepalive.test.ts | 3 +- packages/vue/test/e2e/basic.test.ts | 4 +- packages/vue/test/e2e/keys.test.ts | 5 +- packages/vue/test/e2e/scripts.test.ts | 3 +- packages/vue/test/e2e/shorthands.test.ts | 3 +- packages/vue/test/ssr/asyncSetup.test.ts | 3 +- .../vue/test/ssr/customAugmentation.test.ts | 3 +- packages/vue/test/ssr/normalise.test.ts | 2 +- packages/vue/test/ssr/templateParams.test.ts | 2 +- packages/vue/test/util.ts | 10 ++-- pnpm-lock.yaml | 17 ++----- test/bench/ssr-harlanzw-com-e2e.bench.ts | 3 +- test/unhead/e2e/e2e.test.ts | 4 +- test/unhead/ssr/templateParams.test.ts | 4 +- test/util.ts | 10 +++- 58 files changed, 211 insertions(+), 230 deletions(-) delete mode 100644 packages/dom/README.md delete mode 100644 packages/dom/export-size-report.json delete mode 100644 packages/ssr/README.md delete mode 100644 packages/ssr/export-size-report.json create mode 100644 packages/unhead/client.d.ts create mode 100644 packages/unhead/legacy.d.ts create mode 100644 packages/unhead/server.d.ts create mode 100644 packages/unhead/src/client/createHead.ts rename packages/{dom/src => unhead/src/client}/debounced.ts (100%) rename packages/{dom/src => unhead/src/client}/domPlugin.ts (90%) create mode 100644 packages/unhead/src/client/index.ts rename packages/{dom/src => unhead/src/client}/renderDOMHead.ts (100%) create mode 100644 packages/unhead/src/legacy.ts create mode 100644 packages/unhead/src/server/createHead.ts create mode 100644 packages/unhead/src/server/index.ts rename packages/unhead/src/{ => server}/plugins/payload.ts (100%) rename packages/{ssr/src => unhead/src/server}/renderSSRHead.ts (100%) rename packages/{ssr/src => unhead/src/server}/util/index.ts (100%) rename packages/{ssr/src => unhead/src/server}/util/propsToString.ts (100%) rename packages/{ssr/src => unhead/src/server}/util/ssrRenderTags.ts (100%) rename packages/{ssr/src => unhead/src/server}/util/tagToString.ts (100%) create mode 100644 packages/vue/client.d.ts create mode 100644 packages/vue/server.d.ts create mode 100644 packages/vue/src/client/index.ts create mode 100644 packages/vue/src/server/index.ts diff --git a/examples/vite-ssr-react/src/entry-server.jsx b/examples/vite-ssr-react/src/entry-server.jsx index e4ae98c3..3fc9168c 100644 --- a/examples/vite-ssr-react/src/entry-server.jsx +++ b/examples/vite-ssr-react/src/entry-server.jsx @@ -1,6 +1,6 @@ import ReactDOMServer from 'react-dom/server' import { StaticRouter } from 'react-router-dom/server' -import { createHead } from '../../../packages/unhead/src/createHead' +import { createHead } from 'unhead/server' import { App } from './App' createHead() diff --git a/packages/addons/test/infer-seo-meta.test.ts b/packages/addons/test/infer-seo-meta.test.ts index 0443d1a5..d59ba429 100644 --- a/packages/addons/test/infer-seo-meta.test.ts +++ b/packages/addons/test/infer-seo-meta.test.ts @@ -1,5 +1,5 @@ import { renderSSRHead } from '@unhead/ssr' -import { createHead } from 'unhead' +import { createHead } from 'unhead/server' import { describe, it } from 'vitest' import { InferSeoMetaPlugin } from '../src/plugins/inferSeoMetaPlugin' diff --git a/packages/dom/README.md b/packages/dom/README.md deleted file mode 100644 index 8cbd00cc..00000000 --- a/packages/dom/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# @unhead/dom - -## Install - -```bash -# yarn add @unhead/dom -npm install @unhead/dom -``` - -## Documentation - -See the [@unhead/dom](https://unhead.unjs.io/guide/getting-started/how-it-works#unheaddom) for how this works. diff --git a/packages/dom/export-size-report.json b/packages/dom/export-size-report.json deleted file mode 100644 index cdf4c198..00000000 --- a/packages/dom/export-size-report.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "meta": { - "name": "@unhead/dom", - "dependencies": [ - "@unhead/schema", - "@unhead/shared" - ], - "versions": { - "export-size": "0.7.0", - "esbuild": "^0.19.5" - } - }, - "exports": [ - { - "name": "DomPlugin", - "path": "dist/index.mjs", - "minified": 3126, - "minzipped": 1329, - "bundled": 5210 - }, - { - "name": "debouncedRenderDOMHead", - "path": "dist/index.mjs", - "minified": 2880, - "minzipped": 1222, - "bundled": 4763 - }, - { - "name": "renderDOMHead", - "path": "dist/index.mjs", - "minified": 2692, - "minzipped": 1158, - "bundled": 4429 - } - ] -} diff --git a/packages/dom/package.json b/packages/dom/package.json index f59675f0..2b1061d4 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -29,12 +29,10 @@ "dist" ], "scripts": { - "build": "unbuild .", - "stub": "unbuild . --stub", - "export:sizes": "npx export-size . -r" + "build": "unbuild ", + "stub": "unbuild --stub" }, - "dependencies": { - "@unhead/schema": "workspace:*", - "@unhead/shared": "workspace:*" + "peerDependencies": { + "unhead": "workspace:*" } } diff --git a/packages/dom/src/index.ts b/packages/dom/src/index.ts index 497e8288..d0ff9b7f 100644 --- a/packages/dom/src/index.ts +++ b/packages/dom/src/index.ts @@ -1,3 +1 @@ -export * from './debounced' -export * from './domPlugin' -export * from './renderDOMHead' +export * from 'unhead/client' diff --git a/packages/schema-org/test/e2e/vue.test.ts b/packages/schema-org/test/e2e/vue.test.ts index 85e350e7..b08e36b1 100644 --- a/packages/schema-org/test/e2e/vue.test.ts +++ b/packages/schema-org/test/e2e/vue.test.ts @@ -1,7 +1,8 @@ import { renderDOMHead } from '@unhead/dom' import { defineArticle, defineWebPage, useSchemaOrg } from '@unhead/schema-org/vue' import { renderSSRHead } from '@unhead/ssr' -import { createHead, useHead } from 'unhead' +import { useHead } from 'unhead' +import { createHead } from 'unhead/client' import { describe, expect, it } from 'vitest' import { useDom } from '../../../../test/fixtures' import { createHeadWithContext } from '../../../../test/util' diff --git a/packages/schema-org/test/index.ts b/packages/schema-org/test/index.ts index dee4dd62..22758360 100644 --- a/packages/schema-org/test/index.ts +++ b/packages/schema-org/test/index.ts @@ -1,7 +1,8 @@ import type { MetaInput } from '@unhead/schema-org' import type { SchemaOrgNode } from '../src/types' import { SchemaOrgUnheadPlugin } from '@unhead/schema-org' -import { createHead, unheadCtx } from 'unhead' +import { unheadCtx } from 'unhead' +import { createHead } from 'unhead/server' export async function injectSchemaOrg(): Promise { // filter for schema.org tag diff --git a/packages/schema-org/test/ssr/xss.test.ts b/packages/schema-org/test/ssr/xss.test.ts index f5dab6ad..613a70d5 100644 --- a/packages/schema-org/test/ssr/xss.test.ts +++ b/packages/schema-org/test/ssr/xss.test.ts @@ -1,6 +1,7 @@ import { defineQuestion, defineWebPage, useSchemaOrg } from '@unhead/schema-org' import { renderSSRHead } from '@unhead/ssr' -import { createHead, unheadCtx, useHead } from 'unhead' +import { unheadCtx, useHead } from 'unhead' +import { createHead } from 'unhead/server' import { describe, expect, it } from 'vitest' import { useSetup } from '..' diff --git a/packages/ssr/README.md b/packages/ssr/README.md deleted file mode 100644 index e1cc8315..00000000 --- a/packages/ssr/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# @unhead/ssr - -## Install - -```bash -# yarn add @unhead/dom -npm install @unhead/ssr -``` - -## Documentation - -See the [Unhead](https://unhead.unjs.io/) for more details. diff --git a/packages/ssr/export-size-report.json b/packages/ssr/export-size-report.json deleted file mode 100644 index 9810d684..00000000 --- a/packages/ssr/export-size-report.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "meta": { - "name": "@unhead/ssr", - "dependencies": [ - "@unhead/schema", - "@unhead/shared" - ], - "versions": { - "export-size": "0.7.0", - "esbuild": "^0.19.5" - } - }, - "exports": [ - { - "name": "renderSSRHead", - "path": "dist/index.mjs", - "minified": 1542, - "minzipped": 656, - "bundled": 2665 - }, - { - "name": "ssrRenderTags", - "path": "dist/index.mjs", - "minified": 1182, - "minzipped": 539, - "bundled": 2059 - }, - { - "name": "tagToString", - "path": "dist/index.mjs", - "minified": 752, - "minzipped": 371, - "bundled": 1340 - }, - { - "name": "propsToString", - "path": "dist/index.mjs", - "minified": 248, - "minzipped": 171, - "bundled": 502 - }, - { - "name": "escapeHtml", - "path": "dist/index.mjs", - "minified": 249, - "minzipped": 136, - "bundled": 504 - } - ] -} diff --git a/packages/ssr/package.json b/packages/ssr/package.json index e6a927ea..e22477de 100644 --- a/packages/ssr/package.json +++ b/packages/ssr/package.json @@ -30,11 +30,9 @@ ], "scripts": { "build": "unbuild .", - "stub": "unbuild . --stub", - "export:sizes": "npx export-size . -r" + "stub": "unbuild . --stub" }, - "dependencies": { - "@unhead/schema": "workspace:*", - "@unhead/shared": "workspace:*" + "peerDependencies": { + "unhead": "workspace:*" } } diff --git a/packages/ssr/src/index.ts b/packages/ssr/src/index.ts index 91b4bd3e..f0d31490 100644 --- a/packages/ssr/src/index.ts +++ b/packages/ssr/src/index.ts @@ -1,3 +1 @@ -export * from './renderSSRHead' -export * from './util' -export type { SSRHeadPayload } from '@unhead/schema' +export * from 'unhead/server' diff --git a/packages/unhead/build.config.ts b/packages/unhead/build.config.ts index af309168..896862c8 100644 --- a/packages/unhead/build.config.ts +++ b/packages/unhead/build.config.ts @@ -9,5 +9,8 @@ export default defineBuildConfig({ entries: [ { input: 'src/index', name: 'index' }, { input: 'src/optionalPlugins/index', name: 'optionalPlugins' }, + { input: 'src/server/index', name: 'server' }, + { input: 'src/client/index', name: 'client' }, + { input: 'src/legacy', name: 'legacy' }, ], }) diff --git a/packages/unhead/client.d.ts b/packages/unhead/client.d.ts new file mode 100644 index 00000000..875737f2 --- /dev/null +++ b/packages/unhead/client.d.ts @@ -0,0 +1 @@ +export * from './dist/client' diff --git a/packages/unhead/legacy.d.ts b/packages/unhead/legacy.d.ts new file mode 100644 index 00000000..39833cfa --- /dev/null +++ b/packages/unhead/legacy.d.ts @@ -0,0 +1 @@ +export * from './dist/legacy' diff --git a/packages/unhead/package.json b/packages/unhead/package.json index 2d262949..35fc067d 100644 --- a/packages/unhead/package.json +++ b/packages/unhead/package.json @@ -29,6 +29,16 @@ "types": "./dist/optionalPlugins.d.ts", "import": "./dist/optionalPlugins.mjs", "require": "./dist/optionalPlugins.cjs" + }, + "./server": { + "types": "./dist/server.d.ts", + "import": "./dist/server.mjs", + "require": "./dist/server.cjs" + }, + "./client": { + "types": "./dist/client.d.ts", + "import": "./dist/client.mjs", + "require": "./dist/client.cjs" } }, "main": "dist/index.cjs", @@ -38,12 +48,24 @@ "*": { "optionalPlugins": [ "dist/optionalPlugins" + ], + "server": [ + "dist/server" + ], + "client": [ + "dist/client" + ], + "legacy": [ + "dist/legacy" ] } }, "files": [ + "client.d.ts", "dist", - "optionalPlugins.d.ts" + "legacy.d.ts", + "optionalPlugins.d.ts", + "server.d.ts" ], "scripts": { "build": "unbuild .", @@ -51,7 +73,6 @@ "export:sizes": "npx export-size . -r" }, "dependencies": { - "@unhead/dom": "workspace:*", "@unhead/schema": "workspace:*", "@unhead/shared": "workspace:*", "hookable": "^5.5.3", diff --git a/packages/unhead/server.d.ts b/packages/unhead/server.d.ts new file mode 100644 index 00000000..ecf941a4 --- /dev/null +++ b/packages/unhead/server.d.ts @@ -0,0 +1 @@ +export * from './dist/server' diff --git a/packages/unhead/src/client/createHead.ts b/packages/unhead/src/client/createHead.ts new file mode 100644 index 00000000..b0666e6d --- /dev/null +++ b/packages/unhead/src/client/createHead.ts @@ -0,0 +1,18 @@ +import type { CreateHeadOptions, Head } from '@unhead/schema' +import { IsBrowser } from '@unhead/shared' +import { unheadCtx } from '../context' +import { createHeadCore } from '../createHead' +import { DomPlugin } from './domPlugin' + +export function createHead = Head>(options: CreateHeadOptions = {}) { + const head = createHeadCore({ + document: (IsBrowser ? document : undefined), + ...options, + }) + head.use(DomPlugin()) + // should only be one instance client-side + if (!head.ssr && IsBrowser) { + unheadCtx.set(head, true) + } + return head +} diff --git a/packages/dom/src/debounced.ts b/packages/unhead/src/client/debounced.ts similarity index 100% rename from packages/dom/src/debounced.ts rename to packages/unhead/src/client/debounced.ts diff --git a/packages/dom/src/domPlugin.ts b/packages/unhead/src/client/domPlugin.ts similarity index 90% rename from packages/dom/src/domPlugin.ts rename to packages/unhead/src/client/domPlugin.ts index db1473c5..ac6f7a16 100644 --- a/packages/dom/src/domPlugin.ts +++ b/packages/unhead/src/client/domPlugin.ts @@ -6,7 +6,7 @@ export interface DomPluginOptions extends RenderDomHeadOptions { delayFn?: (fn: () => void) => void } -/* @__NO_SIDE_EFFECTS__ */ export function DomPlugin(options?: DomPluginOptions) { +export function DomPlugin(options?: DomPluginOptions) { return defineHeadPlugin((head) => { // restore initial entry from payload (titleTemplate and templateParams) const initialPayload = head.resolvedOptions.document?.head.querySelector('script[id="unhead:payload"]')?.innerHTML || false diff --git a/packages/unhead/src/client/index.ts b/packages/unhead/src/client/index.ts new file mode 100644 index 00000000..05497f7a --- /dev/null +++ b/packages/unhead/src/client/index.ts @@ -0,0 +1,4 @@ +export * from './createHead' +export * from './debounced' +export * from './domPlugin' +export * from './renderDOMHead' diff --git a/packages/dom/src/renderDOMHead.ts b/packages/unhead/src/client/renderDOMHead.ts similarity index 100% rename from packages/dom/src/renderDOMHead.ts rename to packages/unhead/src/client/renderDOMHead.ts diff --git a/packages/unhead/src/createHead.ts b/packages/unhead/src/createHead.ts index 114945a8..5b8ad6f0 100644 --- a/packages/unhead/src/createHead.ts +++ b/packages/unhead/src/createHead.ts @@ -9,35 +9,16 @@ import type { RuntimeMode, Unhead, } from '@unhead/schema' -import { DomPlugin } from '@unhead/dom' -import { IsBrowser, normaliseEntryTags } from '@unhead/shared' +import { normaliseEntryTags } from '@unhead/shared' import { createHooks } from 'hookable' -import { unheadCtx } from './context' import DedupePlugin from './plugins/dedupe' import EventHandlersPlugin from './plugins/eventHandlers' import HashKeyedPlugin from './plugins/hashKeyed' -import PayloadPlugin from './plugins/payload' import SortPlugin from './plugins/sort' import TemplateParamsPlugin from './plugins/templateParams' import TitleTemplatePlugin from './plugins/titleTemplate' import XSSPlugin from './plugins/xss' -// TODO rename to createDomHead -export function createHead = Head>(options: CreateHeadOptions = {}) { - const head = createHeadCore(options) - head.use(DomPlugin()) - // should only be one instance client-side - if (!head.ssr && IsBrowser) { - unheadCtx.set(head, true) - } - return head -} - -export function createServerHead = Head>(options: CreateHeadOptions = {}) { - // @ts-expect-error untyped - return createHeadCore({ ...options, document: false }) -} - function filterMode(mode: RuntimeMode | undefined, ssr: boolean) { return !mode || (mode === 'server' && ssr) || (mode === 'client' && !ssr) } @@ -51,7 +32,6 @@ export function createHeadCore = Head>(options: Cr // counter for keeping unique ids of head object entries const hooks = createHooks() hooks.addHooks(options.hooks || {}) - options.document = typeof options.document !== 'undefined' ? options.document : (IsBrowser ? document : undefined) const ssr = !options.document const updated = () => { @@ -134,7 +114,6 @@ export function createHeadCore = Head>(options: Cr } ;[ DedupePlugin, - PayloadPlugin, EventHandlersPlugin, HashKeyedPlugin, SortPlugin, diff --git a/packages/unhead/src/index.ts b/packages/unhead/src/index.ts index d95576f3..0e139c3e 100644 --- a/packages/unhead/src/index.ts +++ b/packages/unhead/src/index.ts @@ -1,21 +1,12 @@ -import { createHead, createHeadCore, createServerHead } from './createHead' - -// create -export { - createHead, - createHeadCore, - createServerHead, -} - -// composables export * from './autoImports' export * from './composables/useHead' - export * from './composables/useHeadSafe' export * from './composables/useScript' export * from './composables/useSeoMeta' export * from './composables/useServerHead' export * from './composables/useServerHeadSafe' export * from './composables/useServerSeoMeta' + export * from './context' +export * from './createHead' diff --git a/packages/unhead/src/legacy.ts b/packages/unhead/src/legacy.ts new file mode 100644 index 00000000..83cff701 --- /dev/null +++ b/packages/unhead/src/legacy.ts @@ -0,0 +1,29 @@ +import type { CreateHeadOptions, Head } from '@unhead/schema' +import { IsBrowser } from '@unhead/shared' +import { DomPlugin } from './client/domPlugin' +import { unheadCtx } from './context' +import { createHeadCore } from './createHead' +import { DeprecationsPlugin } from './optionalPlugins/deprecations' +import { PromisesPlugin } from './optionalPlugins/promises' + +export function createServerHead = Head>(options: CreateHeadOptions = {}) { + // @ts-expect-error untyped + const head = createHeadCore({ disableCapoSorting: true, ...options, document: false }) + head.use(DeprecationsPlugin) + head.use(PromisesPlugin) + return head +} + +export function createHead = Head>(options: CreateHeadOptions = {}) { + const head = createHeadCore({ disableCapoSorting: true, ...options }) + head.use(DomPlugin()) + head.use(DeprecationsPlugin) + head.use(PromisesPlugin) + // should only be one instance client-side + if (!head.ssr && IsBrowser) { + unheadCtx.set(head, true) + } + return head +} + +export { createHeadCore } diff --git a/packages/unhead/src/server/createHead.ts b/packages/unhead/src/server/createHead.ts new file mode 100644 index 00000000..f58709d1 --- /dev/null +++ b/packages/unhead/src/server/createHead.ts @@ -0,0 +1,10 @@ +import type { CreateHeadOptions, Head } from '@unhead/schema' +import { createHeadCore } from '../createHead' +import PayloadPlugin from './plugins/payload' + +export function createHead = Head>(options: CreateHeadOptions = {}) { + // @ts-expect-error untyped + const head = createHeadCore({ ...options, document: false }) + head.use(PayloadPlugin) + return head +} diff --git a/packages/unhead/src/server/index.ts b/packages/unhead/src/server/index.ts new file mode 100644 index 00000000..be1769bd --- /dev/null +++ b/packages/unhead/src/server/index.ts @@ -0,0 +1,4 @@ +export * from './createHead' +export * from './renderSSRHead' +export * from './util' +export type { SSRHeadPayload } from '@unhead/schema' diff --git a/packages/unhead/src/plugins/payload.ts b/packages/unhead/src/server/plugins/payload.ts similarity index 100% rename from packages/unhead/src/plugins/payload.ts rename to packages/unhead/src/server/plugins/payload.ts diff --git a/packages/ssr/src/renderSSRHead.ts b/packages/unhead/src/server/renderSSRHead.ts similarity index 100% rename from packages/ssr/src/renderSSRHead.ts rename to packages/unhead/src/server/renderSSRHead.ts diff --git a/packages/ssr/src/util/index.ts b/packages/unhead/src/server/util/index.ts similarity index 100% rename from packages/ssr/src/util/index.ts rename to packages/unhead/src/server/util/index.ts diff --git a/packages/ssr/src/util/propsToString.ts b/packages/unhead/src/server/util/propsToString.ts similarity index 100% rename from packages/ssr/src/util/propsToString.ts rename to packages/unhead/src/server/util/propsToString.ts diff --git a/packages/ssr/src/util/ssrRenderTags.ts b/packages/unhead/src/server/util/ssrRenderTags.ts similarity index 100% rename from packages/ssr/src/util/ssrRenderTags.ts rename to packages/unhead/src/server/util/ssrRenderTags.ts diff --git a/packages/ssr/src/util/tagToString.ts b/packages/unhead/src/server/util/tagToString.ts similarity index 100% rename from packages/ssr/src/util/tagToString.ts rename to packages/unhead/src/server/util/tagToString.ts diff --git a/packages/vue/build.config.ts b/packages/vue/build.config.ts index e4a928c3..1afa17f6 100644 --- a/packages/vue/build.config.ts +++ b/packages/vue/build.config.ts @@ -10,5 +10,7 @@ export default defineBuildConfig({ entries: [ { input: 'src/index', name: 'index' }, { input: 'src/components/index', name: 'components' }, + { input: 'src/server/index', name: 'server' }, + { input: 'src/client/index', name: 'client' }, ], }) diff --git a/packages/vue/client.d.ts b/packages/vue/client.d.ts new file mode 100644 index 00000000..875737f2 --- /dev/null +++ b/packages/vue/client.d.ts @@ -0,0 +1 @@ +export * from './dist/client' diff --git a/packages/vue/package.json b/packages/vue/package.json index 38eebf05..aa833d1c 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -25,6 +25,16 @@ "types": "./dist/components.d.ts", "import": "./dist/components.mjs", "require": "./dist/components.cjs" + }, + "./server": { + "types": "./dist/server.d.ts", + "import": "./dist/server.mjs", + "require": "./dist/server.cjs" + }, + "./client": { + "types": "./dist/client.d.ts", + "import": "./dist/client.mjs", + "require": "./dist/client.cjs" } }, "main": "dist/index.cjs", @@ -34,11 +44,19 @@ "*": { "components": [ "dist/components" + ], + "server": [ + "dist/server" + ], + "client": [ + "dist/client" ] } }, "files": [ - "dist" + "client.d.ts", + "dist", + "server.d.ts" ], "scripts": { "build": "unbuild .", diff --git a/packages/vue/server.d.ts b/packages/vue/server.d.ts new file mode 100644 index 00000000..ecf941a4 --- /dev/null +++ b/packages/vue/server.d.ts @@ -0,0 +1 @@ +export * from './dist/server' diff --git a/packages/vue/src/client/index.ts b/packages/vue/src/client/index.ts new file mode 100644 index 00000000..602c989f --- /dev/null +++ b/packages/vue/src/client/index.ts @@ -0,0 +1,14 @@ +import type { CreateHeadOptions, MergeHead } from '@unhead/schema' +import type { MaybeComputedRef, ReactiveHead, VueHeadClient } from '@unhead/vue' +import { createHead as _createHead } from 'unhead/client' +import { nextTick } from 'vue' +import { vueInstall } from '../createHead' +import VueReactivityPlugin from '../plugins/VueReactivityPlugin' + +export function createHead(options: CreateHeadOptions = {}): VueHeadClient { + options.domDelayFn = options.domDelayFn || (fn => nextTick(() => setTimeout(() => fn(), 0))) + const head = _createHead>>(options) as VueHeadClient + head.use(VueReactivityPlugin) + head.install = vueInstall(head) + return head +} diff --git a/packages/vue/src/createHead.ts b/packages/vue/src/createHead.ts index 187407ab..423e1bf3 100644 --- a/packages/vue/src/createHead.ts +++ b/packages/vue/src/createHead.ts @@ -1,13 +1,9 @@ -import type { CreateHeadOptions, MergeHead } from '@unhead/schema' import type { Plugin } from 'vue' -import type { MaybeComputedRef, ReactiveHead, VueHeadClient } from './types' -import { createHead as _createHead, createServerHead as _createServerHead } from 'unhead' -import { nextTick } from 'vue' -import VueReactivityPlugin from './plugins/VueReactivityPlugin' +import type { VueHeadClient } from './types' export const headSymbol = 'usehead' -function vueInstall(head: VueHeadClient) { +export function vueInstall(head: VueHeadClient) { const plugin = { install(app) { app.config.globalProperties.$unhead = head @@ -18,19 +14,3 @@ function vueInstall(head: VueHeadClient) { } return plugin.install } - -export function createServerHead(options: Omit = {}): VueHeadClient { - const head = _createServerHead>>(options) as VueHeadClient - head.use(VueReactivityPlugin) - head.install = vueInstall(head) - return head -} - -// TODO rename to createDOMHead -export function createHead(options: CreateHeadOptions = {}): VueHeadClient { - options.domDelayFn = options.domDelayFn || (fn => nextTick(() => setTimeout(() => fn(), 0))) - const head = _createHead>>(options) as VueHeadClient - head.use(VueReactivityPlugin) - head.install = vueInstall(head) - return head -} diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index d1e395b9..ba6341b7 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -1,12 +1,8 @@ -import { createHeadCore, unheadCtx } from 'unhead' -import { createHead, createServerHead } from './createHead' +import { unheadCtx } from 'unhead' import { resolveUnrefHeadInput } from './utils' // create export { - createHead, - createHeadCore, - createServerHead, unheadCtx, } diff --git a/packages/vue/src/server/index.ts b/packages/vue/src/server/index.ts new file mode 100644 index 00000000..dc27eb5c --- /dev/null +++ b/packages/vue/src/server/index.ts @@ -0,0 +1,12 @@ +import type { CreateHeadOptions, MergeHead } from '@unhead/schema' +import type { MaybeComputedRef, ReactiveHead, VueHeadClient } from '@unhead/vue' +import { createHead as _createServerHead } from 'unhead/server' +import { vueInstall } from '../createHead' +import VueReactivityPlugin from '../plugins/VueReactivityPlugin' + +export function createHead(options: Omit = {}): VueHeadClient { + const head = _createServerHead>>(options) as VueHeadClient + head.use(VueReactivityPlugin) + head.install = vueInstall(head) + return head +} diff --git a/packages/vue/test/dom/innerContent.test.ts b/packages/vue/test/dom/innerContent.test.ts index d56be700..39153085 100644 --- a/packages/vue/test/dom/innerContent.test.ts +++ b/packages/vue/test/dom/innerContent.test.ts @@ -1,7 +1,7 @@ // @vitest-environment jsdom import { renderDOMHead } from '@unhead/dom' -import { createHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/client' import { describe, it } from 'vitest' import { useDom } from '../../../../test/fixtures' diff --git a/packages/vue/test/dom/keepalive.test.ts b/packages/vue/test/dom/keepalive.test.ts index 5611a654..8a85c3c6 100644 --- a/packages/vue/test/dom/keepalive.test.ts +++ b/packages/vue/test/dom/keepalive.test.ts @@ -1,6 +1,7 @@ // @vitest-environment jsdom -import { createHead, injectHead, useHead } from '@unhead/vue' +import { injectHead, useHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/client' import { describe, it } from 'vitest' import { defineComponent, h, KeepAlive, nextTick, ref } from 'vue' import { mount } from '../util' diff --git a/packages/vue/test/e2e/basic.test.ts b/packages/vue/test/e2e/basic.test.ts index f1780f95..f0beee46 100644 --- a/packages/vue/test/e2e/basic.test.ts +++ b/packages/vue/test/e2e/basic.test.ts @@ -3,7 +3,9 @@ import type { ReactiveHead } from '@unhead/vue' import { renderDOMHead } from '@unhead/dom' import { renderSSRHead } from '@unhead/ssr' -import { createHead, createServerHead, unheadCtx, useHead, useServerHead } from '@unhead/vue' +import { unheadCtx, useHead, useServerHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/client' +import { createHead as createServerHead } from '@unhead/vue/server' import { describe, it } from 'vitest' import { useDom } from '../../../../test/fixtures' import { csrVueAppWithUnhead, ssrVueAppWithUnhead } from '../util' diff --git a/packages/vue/test/e2e/keys.test.ts b/packages/vue/test/e2e/keys.test.ts index cfbbfe20..b7d962e6 100644 --- a/packages/vue/test/e2e/keys.test.ts +++ b/packages/vue/test/e2e/keys.test.ts @@ -1,7 +1,8 @@ import type { ReactiveHead } from '@unhead/vue' import { renderDOMHead } from '@unhead/dom' import { renderSSRHead } from '@unhead/ssr' -import { createHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/client' +import { createHead as createServerHead } from '@unhead/vue/server' import { describe, it } from 'vitest' import { useDom } from '../../../../test/fixtures' @@ -16,7 +17,7 @@ describe('vue e2e keys', () => { } // ssr render on the index page - const ssrHead = createHead() + const ssrHead = createServerHead() ssrHead.push(IndexSchema) diff --git a/packages/vue/test/e2e/scripts.test.ts b/packages/vue/test/e2e/scripts.test.ts index 64849beb..4cec9ce0 100644 --- a/packages/vue/test/e2e/scripts.test.ts +++ b/packages/vue/test/e2e/scripts.test.ts @@ -1,4 +1,5 @@ -import { createHead, useScript } from '@unhead/vue' +import { useScript } from '@unhead/vue' +import { createHead } from '@unhead/vue/client' import { describe, it } from 'vitest' import { ref, watch } from 'vue' import { useDom } from '../../../../test/fixtures' diff --git a/packages/vue/test/e2e/shorthands.test.ts b/packages/vue/test/e2e/shorthands.test.ts index e1926d14..fc85cf7e 100644 --- a/packages/vue/test/e2e/shorthands.test.ts +++ b/packages/vue/test/e2e/shorthands.test.ts @@ -2,7 +2,8 @@ import { renderDOMHead } from '@unhead/dom' import { renderSSRHead } from '@unhead/ssr' -import { createHead, unheadCtx, useHead } from '@unhead/vue' +import { unheadCtx, useHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/client' import { describe, it } from 'vitest' import { useDom } from '../../../../test/fixtures' import { csrVueAppWithUnhead, ssrVueAppWithUnhead } from '../util' diff --git a/packages/vue/test/ssr/asyncSetup.test.ts b/packages/vue/test/ssr/asyncSetup.test.ts index 457a99b4..57970ea6 100644 --- a/packages/vue/test/ssr/asyncSetup.test.ts +++ b/packages/vue/test/ssr/asyncSetup.test.ts @@ -1,5 +1,6 @@ import { renderSSRHead } from '@unhead/ssr' -import { createHead, useHead } from '@unhead/vue' +import { useHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/server' import { renderToString } from '@vue/server-renderer' import { describe, expect, it } from 'vitest' import { createSSRApp, ref } from 'vue' diff --git a/packages/vue/test/ssr/customAugmentation.test.ts b/packages/vue/test/ssr/customAugmentation.test.ts index 66eae6f8..266729ba 100644 --- a/packages/vue/test/ssr/customAugmentation.test.ts +++ b/packages/vue/test/ssr/customAugmentation.test.ts @@ -1,6 +1,7 @@ import type { MergeHead } from '@unhead/schema' import { renderSSRHead } from '@unhead/ssr' -import { createHead, useHead } from '@unhead/vue' +import { useHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/server' import { renderToString } from '@vue/server-renderer' import { createSSRApp, ref } from 'vue' diff --git a/packages/vue/test/ssr/normalise.test.ts b/packages/vue/test/ssr/normalise.test.ts index c295876b..a9ff9192 100644 --- a/packages/vue/test/ssr/normalise.test.ts +++ b/packages/vue/test/ssr/normalise.test.ts @@ -1,5 +1,5 @@ import { renderSSRHead } from '@unhead/ssr' -import { createHead } from '@unhead/vue' +import { createHead } from '@unhead/vue/server' import { describe, expect, it } from 'vitest' describe('normalise', () => { diff --git a/packages/vue/test/ssr/templateParams.test.ts b/packages/vue/test/ssr/templateParams.test.ts index 449ab245..6231580b 100644 --- a/packages/vue/test/ssr/templateParams.test.ts +++ b/packages/vue/test/ssr/templateParams.test.ts @@ -1,5 +1,5 @@ import { renderSSRHead } from '@unhead/ssr' -import { createHead } from 'unhead' +import { createHead } from 'unhead/server' import { describe, it } from 'vitest' import { ref } from 'vue' import { ssrRenderOptionsHead } from '../util' diff --git a/packages/vue/test/util.ts b/packages/vue/test/util.ts index 4ab24271..76880b34 100644 --- a/packages/vue/test/util.ts +++ b/packages/vue/test/util.ts @@ -4,12 +4,14 @@ import type { CreateHeadOptions } from '@unhead/schema' import type { JSDOM } from 'jsdom' import type { App, Component } from 'vue' import { renderSSRHead } from '@unhead/ssr' -import { createHead, createServerHead, VueHeadMixin } from '@unhead/vue' +import { VueHeadMixin } from '@unhead/vue' +import { createHead as createClientHead } from '@unhead/vue/client' +import { createHead as createServerHead } from '@unhead/vue/server' import { renderToString } from '@vue/server-renderer' import { createApp, createSSRApp, h } from 'vue' export function csrVueAppWithUnhead(dom: JSDOM, fn: () => void | Promise) { - const head = createHead({ + const head = createClientHead({ document: dom.window.document, }) const app = createApp({ @@ -43,7 +45,7 @@ export async function ssrVueAppWithUnhead(fn: () => void | Promise, option } export async function ssrRenderHeadToString(fn: () => void) { - const head = createHead() + const head = createServerHead() const app = createSSRApp({ setup() { fn() @@ -57,7 +59,7 @@ export async function ssrRenderHeadToString(fn: () => void) { } export async function ssrRenderOptionsHead(input: any) { - const head = createHead() + const head = createServerHead() const app = createSSRApp({ head() { return input diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7583919a..177b82ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -233,12 +233,9 @@ importers: packages/dom: dependencies: - '@unhead/schema': - specifier: workspace:* - version: link:../schema - '@unhead/shared': + unhead: specifier: workspace:* - version: link:../shared + version: link:../unhead packages/schema: dependencies: @@ -288,18 +285,12 @@ importers: packages/ssr: dependencies: - '@unhead/schema': - specifier: workspace:* - version: link:../schema - '@unhead/shared': + unhead: specifier: workspace:* - version: link:../shared + version: link:../unhead packages/unhead: dependencies: - '@unhead/dom': - specifier: workspace:* - version: link:../dom '@unhead/schema': specifier: workspace:* version: link:../schema diff --git a/test/bench/ssr-harlanzw-com-e2e.bench.ts b/test/bench/ssr-harlanzw-com-e2e.bench.ts index aeecf0c4..5147cdd9 100644 --- a/test/bench/ssr-harlanzw-com-e2e.bench.ts +++ b/test/bench/ssr-harlanzw-com-e2e.bench.ts @@ -2,7 +2,8 @@ import type { Head } from '@unhead/schema' import { InferSeoMetaPlugin } from '@unhead/addons' import { definePerson, defineWebPage, defineWebSite, UnheadSchemaOrg, useSchemaOrg } from '@unhead/schema-org' import { renderSSRHead } from '@unhead/ssr' -import { createServerHead, unheadCtx, useHead, useSeoMeta, useServerHead } from 'unhead' +import { createHead as createServerHead } from '@unhead/vue/server' +import { unheadCtx, useHead, useSeoMeta, useServerHead } from 'unhead' import { bench, describe } from 'vitest' describe('ssr e2e bench', () => { diff --git a/test/unhead/e2e/e2e.test.ts b/test/unhead/e2e/e2e.test.ts index c12e5cc7..517cfee7 100644 --- a/test/unhead/e2e/e2e.test.ts +++ b/test/unhead/e2e/e2e.test.ts @@ -4,13 +4,13 @@ import { renderSSRHead } from '@unhead/ssr' import { useHead, useServerHead } from 'unhead' import { describe, it } from 'vitest' import { useDom } from '../../fixtures' -import { createHeadWithContext } from '../../util' +import { createHeadWithContext, createServerHeadWithContext } from '../../util' describe('unhead e2e', () => { it('basic hydration', async () => { // scenario: we are injecting root head schema which will not have a hydration step, // but we are also injecting a child head schema which will have a hydration step - const ssrHead = createHeadWithContext() + const ssrHead = createServerHeadWithContext() // i.e App.vue useServerHead({ title: 'My amazing site', diff --git a/test/unhead/ssr/templateParams.test.ts b/test/unhead/ssr/templateParams.test.ts index 1b348d4b..00be2784 100644 --- a/test/unhead/ssr/templateParams.test.ts +++ b/test/unhead/ssr/templateParams.test.ts @@ -1,7 +1,7 @@ import { renderSSRHead } from '@unhead/ssr' import { describe, it } from 'vitest' -import { createHeadWithContext } from '../../util' +import { createHeadWithContext, createServerHeadWithContext } from '../../util' describe('ssr templateParams', () => { it('basic', async () => { @@ -92,7 +92,7 @@ describe('ssr templateParams', () => { }) it('ssr payload', async () => { - const head = createHeadWithContext() + const head = createServerHeadWithContext() head.push({ title: 'test', titleTemplate: '%s %separator %siteName', diff --git a/test/util.ts b/test/util.ts index 409e8374..28b3bcf4 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,7 +1,15 @@ -import { createHead, unheadCtx } from 'unhead' +import { unheadCtx } from 'unhead' +import { createHead } from 'unhead/client' +import { createHead as createServerHead } from 'unhead/server' export function createHeadWithContext(options?: any) { const head = createHead(options) unheadCtx.set(head, true) return head } + +export function createServerHeadWithContext(options?: any) { + const head = createServerHead(options) + unheadCtx.set(head, true) + return head +}