Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/modern-emus-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik.dev/core': minor
---

FEAT: `getClientManifest()` is now the way to get the client build manifest. Importing from `@qwik-client-manifest` is deprecated.
14 changes: 14 additions & 0 deletions packages/docs/src/routes/api/qwik/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,20 @@
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts",
"mdFile": "core.functioncomponent.md"
},
{
"name": "getClientManifest",
"id": "getclientmanifest",
"hierarchy": [
{
"name": "getClientManifest",
"id": "getclientmanifest"
}
],
"kind": "Function",
"content": "Returns the client build manifest, which includes the mappings from symbols to bundles, the bundlegraph etc.\n\n\n```typescript\ngetClientManifest: () => ServerQwikManifest\n```\n**Returns:**\n\nServerQwikManifest",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/get-client-manifest.ts",
"mdFile": "core.getclientmanifest.md"
},
{
"name": "getDomContainer",
"id": "getdomcontainer",
Expand Down
14 changes: 14 additions & 0 deletions packages/docs/src/routes/api/qwik/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,20 @@ export type FunctionComponent<P = unknown> = {

[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts)

<h2 id="getclientmanifest">getClientManifest</h2>

Returns the client build manifest, which includes the mappings from symbols to bundles, the bundlegraph etc.

```typescript
getClientManifest: () => ServerQwikManifest;
```

**Returns:**

ServerQwikManifest

[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/get-client-manifest.ts)

<h2 id="getdomcontainer">getDomContainer</h2>

```typescript
Expand Down
3 changes: 1 addition & 2 deletions packages/insights/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"noEmit": true,
"types": ["node", "vite/client"],
"paths": {
"~/*": ["./src/*"],
"@qwik-client-manifest": ["../../qwik/src/server/server-modules.d.ts"]
"~/*": ["./src/*"]
}
},
"exclude": ["./dist", "eslint.config.mjs"]
Expand Down
4 changes: 4 additions & 0 deletions packages/qwik-router/src/buildtime/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import { validatePlugin } from './validate-plugin';
import { getRouterIndexTags, makeRouterDevMiddleware } from './dev-middleware';

export const QWIK_ROUTER_CONFIG_ID = '@qwik-router-config';
/**
* This virtual module is used to generate dynamic entries for user route files, which are added as
* dynamic imports to the qwik-router-config as a way to create new entry points for the build.
*/
const QWIK_ROUTER_ENTRIES_ID = '@qwik-router-entries';
const QWIK_ROUTER = '@qwik.dev/router';
const QWIK_ROUTER_SW_REGISTER = '@qwik-router-sw-register';
Expand Down
1 change: 1 addition & 0 deletions packages/qwik/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"dependencies": {
"csstype": "^3.2.3",
"launch-editor": "^2.12.0",
"magic-string": "0.30.21",
"rollup": "^4.59.0",
"ts-morph": "27.0.2"
},
Expand Down
1 change: 1 addition & 0 deletions packages/qwik/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export { getPlatform, setPlatform } from './shared/platform/platform';
export type { CorePlatform } from './shared/platform/types';
export type { ClientContainer } from './client/types';
export type { DomContainer } from './client/dom-container';
export { getClientManifest } from './shared/get-client-manifest';

//////////////////////////////////////////////////////////////////////////////////////////
// JSX Runtime
Expand Down
4 changes: 4 additions & 0 deletions packages/qwik/src/core/qwik.core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as CSS_2 from 'csstype';
import { isBrowser } from '@qwik.dev/core/build';
import { isDev } from '@qwik.dev/core/build';
import { isServer } from '@qwik.dev/core/build';
import type { ServerQwikManifest } from '@qwik.dev/core/optimizer';

// @public
export const $: <T>(expression: T) => QRL<T>;
Expand Down Expand Up @@ -401,6 +402,9 @@ export type FunctionComponent<P = unknown> = {
renderFn(props: P, key: string | null, flags: number, dev?: DevJSX): JSXOutput;
}['renderFn'];

// @public
export const getClientManifest: () => ServerQwikManifest;

// Warning: (ae-forgotten-export) The symbol "PropsProxy" needs to be exported by the entry point index.d.ts
//
// @internal
Expand Down
17 changes: 17 additions & 0 deletions packages/qwik/src/core/shared/get-client-manifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { ServerQwikManifest } from '@qwik.dev/core/optimizer';

/**
* Returns the client build manifest, which includes the mappings from symbols to bundles, the
* bundlegraph etc.
*
* @public
*/
export const getClientManifest = (): ServerQwikManifest => {
const manifest = (globalThis as any).__QWIK_MANIFEST__ as ServerQwikManifest;
if (!(globalThis as any).__QWIK_MANIFEST__) {
throw new Error(
`Client manifest is not available. It should have been automatically injected during the build process. Make sure that @qwik.dev/core is internal to the build.`
);
}
return manifest;
};
58 changes: 43 additions & 15 deletions packages/qwik/src/optimizer/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
import { convertManifestToBundleGraph } from './bundle-graph';
import { createLinter, type QwikLinter } from './eslint-plugin';
import { isVirtualId, isWin, parseId } from './vite-utils';
import MagicString from 'magic-string';

const REG_CTX_NAME = ['server'];

Expand Down Expand Up @@ -539,6 +540,9 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {
};
}
} else if (pathId.endsWith(QWIK_CLIENT_MANIFEST_ID)) {
console.error(
`${importerId}: importing ${QWIK_CLIENT_MANIFEST_ID} is deprecated. Use \`getClientManifest()\` instead.`
);
debug(`resolveId(${count})`, 'Resolved', QWIK_CLIENT_MANIFEST_ID);
result = {
id: QWIK_CLIENT_MANIFEST_ID,
Expand Down Expand Up @@ -662,7 +666,7 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {
debug(`load(${count})`, QWIK_CLIENT_MANIFEST_ID, opts.buildMode);
return {
moduleSideEffects: false,
code: await getQwikServerManifestModule(isServer),
code: `export const manifest = globalThis.${globalManifestKey}'};\n`,
};
}
/**
Expand Down Expand Up @@ -715,6 +719,7 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {
return null;
};

let theManifest: string | null | undefined;
let transformCount = 0;
const transform = async function (
ctx: Rollup.PluginContext,
Expand All @@ -725,14 +730,17 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {
if (isVirtualId(id)) {
return;
}
const count = transformCount++;
const isServer = getIsServer(transformOpts);
const currentOutputs = isServer ? serverTransformedOutputs : clientTransformedOutputs;
if (currentOutputs.has(id)) {
// This is a QRL segment, and we don't need to process it any further
return;
}

let shouldReturn = false;

const count = transformCount++;

const optimizer = getOptimizer();
const path = getPath();

Expand All @@ -741,6 +749,8 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {
const dir = parsedPathId.dir;
const base = parsedPathId.base;
const ext = parsedPathId.ext.toLowerCase();
let map;
let meta;
if (ext in TRANSFORM_EXTS || TRANSFORM_REGEX.test(pathId)) {
/** Strip client|server code from qwik server|client, but not in lib/test */
const strip = opts.target === 'client' || opts.target === 'ssr';
Expand Down Expand Up @@ -846,19 +856,35 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {

ctx.addWatchFile(id);

return {
code: module.code,
map: module.map,
meta: {
segment: module.segment,
qwikdeps: Array.from(deps),
},
code = module.code;
map = module.map;
meta = {
segment: module.segment,
qwikdeps: Array.from(deps),
};
shouldReturn = true;
}

debug(`transform(${count})`, 'Not transforming', id);
if (code.includes(`globalThis.${globalManifestKey}`)) {
if (theManifest === undefined) {
theManifest = await getQwikServerManifest(getIsServer(transformOpts));
}
const s = new MagicString(code);
// Always replace the check
s.replace(`!globalThis.${globalManifestKey}`, 'false');
if (theManifest) {
s.replace(`globalThis.${globalManifestKey}`, theManifest);
}
code = s.toString();
map ||= s.generateMap({ source: id, includeContent: false });
shouldReturn = true;
debug(`transform(${count})`, `Replaced globalThis.${globalManifestKey} with manifest input`);
}

return null;
if (shouldReturn) {
return { code, map, meta };
}
debug(`transform(${count})`, 'Not transforming', id);
};

type OutputAnalyzer = {
Expand Down Expand Up @@ -957,7 +983,7 @@ export const isDev = ${JSON.stringify(isDev)};
`;
}

async function getQwikServerManifestModule(isServer: boolean) {
async function getQwikServerManifest(isServer: boolean) {
if (
!opts.manifestInput &&
opts.target === 'ssr' &&
Expand Down Expand Up @@ -1001,8 +1027,7 @@ export const isDev = ${JSON.stringify(isDev)};
bundleGraph: manifest.bundleGraph,
};
}
return `// @qwik-client-manifest
export const manifest = ${serverManifest ? JSON.stringify(serverManifest) : 'globalThis.__QWIK_MANIFEST__'};\n`;
return serverManifest && JSON.stringify(serverManifest);
}

function setSourceMapSupport(sourcemap: boolean) {
Expand Down Expand Up @@ -1207,10 +1232,11 @@ export const QWIK_JSX_DEV_RUNTIME_ID = '@qwik.dev/core/jsx-dev-runtime';

export const QWIK_CORE_SERVER = '@qwik.dev/core/server';

/** Internal use only - use `getClientManifest()` instead */
export const QWIK_CLIENT_MANIFEST_ID = '@qwik-client-manifest';

export const QWIK_PRELOADER_ID = '@qwik.dev/core/preloader';

/** @internal virtual import to ensure the _run etc handlers are exported as-is */
export const QWIK_HANDLERS_ID = '@qwik-handlers';

export const SRC_DIR_DEFAULT = 'src';
Expand Down Expand Up @@ -1289,3 +1315,5 @@ export type QwikBuildTarget = 'client' | 'ssr' | 'lib' | 'test';

/** @public */
export type QwikBuildMode = 'production' | 'development';

const globalManifestKey = '__QWIK_MANIFEST__';
2 changes: 1 addition & 1 deletion packages/qwik/src/optimizer/src/plugins/plugin.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ describe('resolveId', () => {
'id',
'@qwik.dev/core/build'
);
expect(await plugin.resolveId(null!, '@qwik-client-manifest', '/foo/bar')).toHaveProperty(
expect(await plugin.resolveId(null!, '@qwik-client-manifest', '/foo/bar/core')).toHaveProperty(
'id',
'@qwik-client-manifest'
);
Expand Down
1 change: 1 addition & 0 deletions packages/qwik/src/server/server-modules.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
declare module '@qwik-client-manifest' {
/** @deprecated Use `getClientManifest()` instead */
const manifest: import('.').ServerQwikManifest;
export { manifest };
}
Expand Down
9 changes: 5 additions & 4 deletions packages/qwik/src/server/ssr-render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { getClientManifest } from '@qwik.dev/core';
import { getSymbolHash, setServerPlatform } from './platform';
import type { JSXOutput, ResolvedManifest, SymbolMapper, StreamWriter } from './qwik-types';
import type { JSXOutput, ResolvedManifest, StreamWriter, SymbolMapper } from './qwik-types';
import { ssrCreateContainer } from './ssr-container';
import { StreamHandler } from './ssr-stream-handler';
import type {
QwikManifest,
RenderToStreamOptions,
Expand All @@ -8,9 +11,6 @@ import type {
RenderToStringResult,
} from './types';
import { getBuildBase } from './utils';
import { ssrCreateContainer } from './ssr-container';
import { manifest as builtManifest } from '@qwik-client-manifest';
import { StreamHandler } from './ssr-stream-handler';

/**
* Creates a server-side `document`, renders to root node to the document, then serializes the
Expand Down Expand Up @@ -102,6 +102,7 @@ export const renderToStream = async (
export function resolveManifest(
manifest?: Partial<QwikManifest | ResolvedManifest> | undefined
): ResolvedManifest | undefined {
const builtManifest = getClientManifest();
const mergedManifest = (manifest ? { ...builtManifest, ...manifest } : builtManifest) as
| ResolvedManifest
| QwikManifest;
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions scripts/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ function generateServerReferenceModules(config: BuildConfig) {
// server-modules.d.ts
const referenceDts = `/// <reference types="./server" />
declare module '@qwik-client-manifest' {
/** @deprecated Use \`getClientManifest()\` instead */
const manifest: import('./optimizer').QwikManifest;
export { manifest };
}
Expand Down
16 changes: 13 additions & 3 deletions scripts/submodule-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ async function submoduleCoreProd(config: BuildConfig): Promise<object> {
const input: InputOptions = {
input: join(config.tscDir, 'packages', 'qwik', 'src', 'core', 'index.js'),
onwarn: rollupOnWarn,
external: ['@qwik.dev/core/build', '@qwik.dev/core/preloader', 'node:async_hooks'],
external: [
'@qwik.dev/core/build',
'@qwik.dev/core/preloader',
'@qwik-client-manifest',
'node:async_hooks',
],
plugins: [
{
name: 'setVersion',
Expand Down Expand Up @@ -78,7 +83,7 @@ async function submoduleCoreProd(config: BuildConfig): Promise<object> {

const inputCore = join(config.distQwikPkgDir, 'core.mjs');
const inputMin: InputOptions = {
external: ['@qwik.dev/core/preloader', 'node:async_hooks'],
external: ['@qwik.dev/core/preloader', '@qwik-client-manifest', 'node:async_hooks'],
input: inputCore,
onwarn: rollupOnWarn,
plugins: [
Expand Down Expand Up @@ -339,7 +344,12 @@ async function submoduleCoreDev(config: BuildConfig) {

const esm = await build({
...opts,
external: ['@qwik.dev/core/build', '@qwik.dev/core/preloader', 'node:async_hooks'],
external: [
'@qwik.dev/core/build',
'@qwik.dev/core/preloader',
'@qwik-client-manifest',
'node:async_hooks',
],
format: 'esm',
outExtension: { '.js': '.mjs' },
});
Expand Down
1 change: 0 additions & 1 deletion scripts/submodule-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export async function submoduleServer(config: BuildConfig, nameCache?: object) {
'@qwik.dev/core',
'@qwik.dev/core/build',
'@qwik.dev/core/preloader',
'@qwik-client-manifest',
],
};

Expand Down
Loading