Skip to content

Commit bc0caa4

Browse files
committed
feat(preloader): add @builder.io/qwik/preloader
separate shared chunk that does preloading and is also imported by qwik
1 parent bb6be68 commit bc0caa4

File tree

30 files changed

+705
-276
lines changed

30 files changed

+705
-276
lines changed

packages/docs/src/repl/bundled.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import qCoreDts from '../../node_modules/@builder.io/qwik/dist/core.d.ts?raw-sou
1414
import qCoreMinMjs from '../../node_modules/@builder.io/qwik/dist/core.min.mjs?raw-source';
1515
import qCoreMjs from '../../node_modules/@builder.io/qwik/dist/core.mjs?raw-source';
1616
import qOptimizerCjs from '../../node_modules/@builder.io/qwik/dist/optimizer.cjs?raw-source';
17+
import qPreloaderMjs from '../../node_modules/@builder.io/qwik/dist/preloader.mjs?raw-source';
1718
import qServerCjs from '../../node_modules/@builder.io/qwik/dist/server.cjs?raw-source';
1819
import qServerDts from '../../node_modules/@builder.io/qwik/dist/server.d.ts?raw-source';
1920
import qWasmCjs from '../../node_modules/@builder.io/qwik/bindings/qwik.wasm.cjs?raw-source';
@@ -55,6 +56,7 @@ export const bundled: PkgUrls = {
5556
'/dist/optimizer.cjs': qOptimizerCjs,
5657
'/dist/server.cjs': qServerCjs,
5758
'/dist/server.d.ts': qServerDts,
59+
'/dist/preloader.mjs': qPreloaderMjs,
5860
'/bindings/qwik.wasm.cjs': qWasmCjs,
5961
'/bindings/qwik_wasm_bg.wasm': qWasmBinUrl,
6062
},

packages/docs/src/repl/worker/repl-plugins.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 's
2929
if (id === '@builder.io/qwik/server') {
3030
return '\0qwikServer';
3131
}
32+
if (id === '@builder.io/qwik/preloader') {
33+
return '\0qwikPreloader';
34+
}
3235
// Simple relative file resolution
3336
if (id.startsWith('./')) {
3437
const extensions = ['', '.tsx', '.ts'];
@@ -69,6 +72,12 @@ export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 's
6972
}
7073
throw new Error(`Unable to load Qwik core`);
7174
}
75+
if (id === '\0qwikPreloader') {
76+
const rsp = await depResponse('@builder.io/qwik', '/preloader.mjs');
77+
if (rsp) {
78+
return rsp.text();
79+
}
80+
}
7281

7382
// We're the fallback, we know all the files
7483
if (/\.[jt]sx?$/.test(id)) {

packages/docs/src/routes/api/qwik-optimizer/api.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@
434434
}
435435
],
436436
"kind": "Interface",
437-
"content": "The metadata of the build. One of its uses is storing where QRL symbols are located.\n\n\n```typescript\nexport interface QwikManifest \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[bundles](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[fileName: string\\]: [QwikBundle](#qwikbundle)<!-- -->; }\n\n\n</td><td>\n\nAll code bundles, used to know the import graph\n\n\n</td></tr>\n<tr><td>\n\n[injections?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[GlobalInjections](#globalinjections)<!-- -->\\[\\]\n\n\n</td><td>\n\n_(Optional)_ CSS etc to inject in the document head\n\n\n</td></tr>\n<tr><td>\n\n[manifestHash](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\nContent hash of the manifest, if this changes, the code changed\n\n\n</td></tr>\n<tr><td>\n\n[mapping](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: string; }\n\n\n</td><td>\n\nWhere QRLs are located\n\n\n</td></tr>\n<tr><td>\n\n[options?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ target?: string; buildMode?: string; entryStrategy?: { \\[key: string\\]: any; }; }\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[platform?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[name: string\\]: string; }\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[symbols](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: [QwikSymbol](#qwiksymbol)<!-- -->; }\n\n\n</td><td>\n\nQRL symbols\n\n\n</td></tr>\n<tr><td>\n\n[version](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
437+
"content": "The metadata of the build. One of its uses is storing where QRL symbols are located.\n\n\n```typescript\nexport interface QwikManifest \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[bundles](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[fileName: string\\]: [QwikBundle](#qwikbundle)<!-- -->; }\n\n\n</td><td>\n\nAll code bundles, used to know the import graph\n\n\n</td></tr>\n<tr><td>\n\n[injections?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[GlobalInjections](#globalinjections)<!-- -->\\[\\]\n\n\n</td><td>\n\n_(Optional)_ CSS etc to inject in the document head\n\n\n</td></tr>\n<tr><td>\n\n[manifestHash](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\nContent hash of the manifest, if this changes, the code changed\n\n\n</td></tr>\n<tr><td>\n\n[mapping](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: string; }\n\n\n</td><td>\n\nWhere QRLs are located\n\n\n</td></tr>\n<tr><td>\n\n[options?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ target?: string; buildMode?: string; entryStrategy?: { \\[key: string\\]: any; }; }\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[platform?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[name: string\\]: string; }\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[preloader?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The preloader bundle\n\n\n</td></tr>\n<tr><td>\n\n[symbols](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: [QwikSymbol](#qwiksymbol)<!-- -->; }\n\n\n</td><td>\n\nQRL symbols\n\n\n</td></tr>\n<tr><td>\n\n[version](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>",
438438
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts",
439439
"mdFile": "qwik.qwikmanifest.md"
440440
},

packages/docs/src/routes/api/qwik-optimizer/index.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,21 @@ _(Optional)_
14631463
</td></tr>
14641464
<tr><td>
14651465

1466+
[preloader?](#)
1467+
1468+
</td><td>
1469+
1470+
</td><td>
1471+
1472+
string
1473+
1474+
</td><td>
1475+
1476+
_(Optional)_ The preloader bundle
1477+
1478+
</td></tr>
1479+
<tr><td>
1480+
14661481
[symbols](#)
14671482

14681483
</td><td>

packages/qwik-city/src/buildtime/vite/get-route-imports.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ export function getRouteImports(routes: BuildRoute[], manifest: QwikManifest) {
1212
: [];
1313
const routeAndLayoutPaths = [routePath, ...layoutPaths];
1414

15-
const imports = [];
15+
const bundles = [];
1616

1717
for (const [bundleName, bundle] of Object.entries(manifest.bundles)) {
1818
if (isBundlePartOfRoute(bundle, routeAndLayoutPaths)) {
19-
imports.push(bundleName);
19+
bundles.push(bundleName);
2020
}
2121
}
22-
if (imports.length > 0) {
23-
result[route.routeName] = { imports };
22+
if (bundles.length > 0) {
23+
result[route.routeName] = { dynamicImports: bundles };
2424
}
2525
});
2626
for (const bundleName of Object.keys(manifest.bundles)) {

packages/qwik-city/src/buildtime/vite/get-route-imports.unit.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ describe('modifyBundleGraph', () => {
5656
expect(actualResult).toMatchInlineSnapshot(`
5757
{
5858
"/": {
59-
"imports": [
59+
"dynamicImports": [
6060
"fake-bundle1.js",
6161
],
6262
},
6363
"/subroute": {
64-
"imports": [
64+
"dynamicImports": [
6565
"fake-bundle-part-of-sub-route.js",
6666
"fake-bundle-part-of-layout.js",
6767
],
@@ -102,7 +102,7 @@ describe('modifyBundleGraph', () => {
102102
expect(actualResult).toMatchInlineSnapshot(`
103103
{
104104
"/": {
105-
"imports": [
105+
"dynamicImports": [
106106
"fake-bundle1.js",
107107
"fake-bundle2.js",
108108
],

packages/qwik-city/src/runtime/src/client-navigate.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { isBrowser, _preload } from '@builder.io/qwik';
1+
import { isBrowser } from '@builder.io/qwik';
2+
// @ts-expect-error we don't have types for the preloader yet
3+
import { p as preload } from '@builder.io/qwik/preloader';
24
import type { NavigationType, ScrollState } from './types';
35
import { isSamePath, toPath } from './utils';
46

@@ -43,6 +45,6 @@ export const prefetchSymbols = (path: string) => {
4345
if (isBrowser) {
4446
path = path.endsWith('/') ? path : path + '/';
4547
path = path.length > 1 && path.startsWith('/') ? path.slice(1) : path;
46-
_preload(path, true);
48+
preload(path);
4749
}
4850
};

packages/qwik-labs/src-vite/insights/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type QwikVitePlugin } from '@builder.io/qwik/optimizer';
1+
import { type QwikVitePlugin, type SmartEntryStrategy } from '@builder.io/qwik/optimizer';
22
import { existsSync, mkdirSync } from 'node:fs';
33
import { readFile, writeFile } from 'node:fs/promises';
44
import { join, resolve } from 'node:path';
@@ -63,9 +63,6 @@ export async function qwikInsights(qwikInsightsOpts: {
6363
throw new Error('Missing vite-plugin-qwik');
6464
}
6565
const opts = qwikVitePlugin.api.getOptions();
66-
if (opts.entryStrategy.type !== 'smart') {
67-
return;
68-
}
6966
if (isProd) {
7067
try {
7168
const qManifest: InsightManifest = { manual: {}, prefetch: [] };
@@ -85,9 +82,12 @@ export async function qwikInsights(qwikInsightsOpts: {
8582
}
8683

8784
if (data) {
88-
opts.entryStrategy.manual = { ...data.manual, ...opts.entryStrategy.manual };
85+
(opts.entryStrategy as SmartEntryStrategy).manual = {
86+
...data.manual,
87+
...(opts.entryStrategy as SmartEntryStrategy).manual,
88+
};
8989

90-
qwikVitePlugin.api.registerBundleGraphAdder(() => {
90+
qwikVitePlugin.api.registerBundleGraphAdder((manifest) => {
9191
const result: Record<
9292
string,
9393
{ imports?: string[] | undefined; dynamicImports?: string[] | undefined }
@@ -101,7 +101,7 @@ export async function qwikInsights(qwikInsightsOpts: {
101101
if (!route.endsWith('/')) {
102102
route += '/';
103103
}
104-
result[route] = { imports: item.symbols };
104+
result[route] = { ...manifest.bundles[route], imports: item.symbols };
105105
}
106106
}
107107
return result;

packages/qwik/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@
109109
"import": "./dist/optimizer.mjs",
110110
"require": "./dist/optimizer.cjs"
111111
},
112+
"./preloader": {
113+
"import": "./dist/preloader.mjs"
114+
},
112115
"./server.cjs": "./dist/server.cjs",
113116
"./server.mjs": "./dist/server.mjs",
114117
"./server": {

packages/qwik/src/core/api.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,9 +624,6 @@ export const PrefetchServiceWorker: (opts: {
624624
nonce?: string;
625625
}) => JSXNode_2<'script'>;
626626

627-
// @internal (undocumented)
628-
export const _preload: (name: string, priority: boolean) => void;
629-
630627
// @public (undocumented)
631628
export interface ProgressHTMLAttributes<T extends Element> extends Attrs<'progress', T> {
632629
}

0 commit comments

Comments
 (0)