@qwik.dev/router 2.0.0-beta.36 → 2.0.0-beta.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/adapters/cloudflare-pages/vite/index.mjs +3 -5
- package/lib/adapters/shared/vite/index.d.ts +3 -4
- package/lib/adapters/shared/vite/index.mjs +167 -155
- package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
- package/lib/chunks/format.mjs +31 -0
- package/lib/chunks/fs.mjs +10 -8
- package/lib/chunks/head.qwik.mjs +1425 -0
- package/lib/chunks/http-error.qwik.mjs +2 -2
- package/lib/chunks/pathname.mjs +3 -32
- package/lib/chunks/request-body-limit.mjs +37 -0
- package/lib/chunks/request-path.mjs +60 -0
- package/lib/chunks/routes.mjs +47 -0
- package/lib/chunks/server-error.mjs +19 -0
- package/lib/chunks/system.mjs +8 -8
- package/lib/chunks/use-functions.qwik.mjs +3 -12
- package/lib/chunks/user-response.mjs +1875 -0
- package/lib/chunks/worker-thread.mjs +317 -0
- package/lib/index.d.ts +251 -44
- package/lib/index.qwik.mjs +734 -485
- package/lib/middleware/aws-lambda/index.mjs +2 -1
- package/lib/middleware/azure-swa/index.mjs +13 -9
- package/lib/middleware/cloudflare-pages/index.mjs +2 -2
- package/lib/middleware/deno/index.d.ts +2 -0
- package/lib/middleware/deno/index.mjs +2 -1
- package/lib/middleware/netlify-edge/index.mjs +2 -2
- package/lib/middleware/node/index.d.ts +9 -1
- package/lib/middleware/node/index.mjs +28 -3
- package/lib/middleware/request-handler/index.d.ts +65 -26
- package/lib/middleware/request-handler/index.mjs +38 -1679
- package/lib/middleware/vercel-edge/index.mjs +2 -2
- package/lib/ssg/index.d.ts +5 -13
- package/lib/ssg/index.mjs +14 -53
- package/lib/vite/index.d.ts +23 -0
- package/lib/vite/index.mjs +533 -122
- package/package.json +4 -3
- package/lib/chunks/deepFreeze.qwik.mjs +0 -18
- package/lib/chunks/error-handler.mjs +0 -57
- package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
- package/lib/chunks/redirect-handler.mjs +0 -6
- package/lib/chunks/routing.qwik.mjs +0 -821
- package/lib/chunks/worker-thread.qwik.mjs +0 -2585
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import { join, relative } from 'node:path';
|
|
3
3
|
import { n as normalizePathSlash } from '../../../chunks/fs.mjs';
|
|
4
|
+
import { e as ensureSlash } from '../../../chunks/pathname.mjs';
|
|
4
5
|
import { viteAdapter } from '../../shared/vite/index.mjs';
|
|
5
6
|
|
|
6
7
|
function cloudflarePagesAdapter(opts = {}) {
|
|
@@ -38,14 +39,11 @@ function cloudflarePagesAdapter(opts = {}) {
|
|
|
38
39
|
publicDir: false
|
|
39
40
|
};
|
|
40
41
|
},
|
|
41
|
-
async generate({ clientOutDir, serverOutDir, basePathname
|
|
42
|
+
async generate({ clientOutDir, serverOutDir, basePathname }) {
|
|
42
43
|
const routesJsonPath = join(clientOutDir, "_routes.json");
|
|
43
44
|
const hasRoutesJson = fs.existsSync(routesJsonPath);
|
|
44
45
|
if (!hasRoutesJson && opts.functionRoutes !== false) {
|
|
45
|
-
|
|
46
|
-
if (!pathName.endsWith("/")) {
|
|
47
|
-
pathName += "/";
|
|
48
|
-
}
|
|
46
|
+
const pathName = ensureSlash(basePathname);
|
|
49
47
|
const routesJson = {
|
|
50
48
|
version: 1,
|
|
51
49
|
include: [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Plugin as Plugin_2 } from 'vite';
|
|
2
2
|
import type { SsgRenderOptions } from 'packages/qwik-router/src/ssg';
|
|
3
|
-
import
|
|
3
|
+
import { UserConfig } from 'vite';
|
|
4
4
|
|
|
5
5
|
/** @public */
|
|
6
6
|
export declare interface AdapterSSGOptions extends Omit<SsgRenderOptions, 'outDir' | 'origin'> {
|
|
@@ -75,7 +75,7 @@ export declare interface ServerAdapterOptions {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/** @public */
|
|
78
|
-
export declare function viteAdapter(opts: ViteAdapterPluginOptions): Plugin_2<
|
|
78
|
+
export declare function viteAdapter(opts: ViteAdapterPluginOptions): Plugin_2<never>[];
|
|
79
79
|
|
|
80
80
|
/** @public */
|
|
81
81
|
declare interface ViteAdapterPluginOptions {
|
|
@@ -93,7 +93,6 @@ declare interface ViteAdapterPluginOptions {
|
|
|
93
93
|
serverOutDir: string;
|
|
94
94
|
basePathname: string;
|
|
95
95
|
routes: BuiltRoute[];
|
|
96
|
-
assetsDir?: string;
|
|
97
96
|
warn: (message: string) => void;
|
|
98
97
|
error: (message: string) => void;
|
|
99
98
|
}) => Promise<void>;
|
|
@@ -1,71 +1,21 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { readFile, unlink, rm } from 'node:fs/promises';
|
|
1
3
|
import { join, resolve, dirname, basename } from 'node:path';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
4
|
import fs from 'node:fs';
|
|
4
|
-
import {
|
|
5
|
+
import { L as LOADER_REGEX } from '../../../chunks/request-path.mjs';
|
|
6
|
+
import { e as ensureSlash } from '../../../chunks/pathname.mjs';
|
|
5
7
|
|
|
6
|
-
const SSG_WORKER_IMPORT_PREFIX = "@qwik-router-ssg-worker/";
|
|
7
|
-
function ssgWorkerImportPlugin() {
|
|
8
|
-
return {
|
|
9
|
-
name: "qwik-router-ssg-worker-imports",
|
|
10
|
-
enforce: "pre",
|
|
11
|
-
async resolveId(id, importer) {
|
|
12
|
-
if (!id.startsWith(SSG_WORKER_IMPORT_PREFIX)) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
const subpath = id.slice(SSG_WORKER_IMPORT_PREFIX.length);
|
|
16
|
-
const sourceId = fileURLToPath(new URL(`../../${subpath}`, import.meta.url));
|
|
17
|
-
const resolved = await this.resolve(sourceId, importer, {
|
|
18
|
-
skipSelf: true
|
|
19
|
-
});
|
|
20
|
-
return `${(resolved ?? {
|
|
21
|
-
id: sourceId
|
|
22
|
-
}).id}?ssg-worker`;
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function normalizeTrailingSlash(pathname) {
|
|
28
|
-
if (!pathname.endsWith("/")) {
|
|
29
|
-
return pathname + "/";
|
|
30
|
-
}
|
|
31
|
-
return pathname;
|
|
32
|
-
}
|
|
33
|
-
function createNotFoundPathsCode(basePathname, notFounds) {
|
|
34
|
-
notFounds.sort((a, b) => {
|
|
35
|
-
if (a[0].length > b[0].length) {
|
|
36
|
-
return -1;
|
|
37
|
-
}
|
|
38
|
-
if (a[0].length < b[0].length) {
|
|
39
|
-
return 1;
|
|
40
|
-
}
|
|
41
|
-
if (a[0] < b[0]) {
|
|
42
|
-
return -1;
|
|
43
|
-
}
|
|
44
|
-
if (a[0] > b[0]) {
|
|
45
|
-
return 1;
|
|
46
|
-
}
|
|
47
|
-
return 0;
|
|
48
|
-
});
|
|
49
|
-
if (!notFounds.some((r) => r[0] === basePathname)) {
|
|
50
|
-
const html = getErrorHtml(404, "Resource Not Found");
|
|
51
|
-
notFounds.push([
|
|
52
|
-
basePathname,
|
|
53
|
-
html
|
|
54
|
-
]);
|
|
55
|
-
}
|
|
56
|
-
return JSON.stringify(notFounds, null, 2).slice(1, -1);
|
|
57
|
-
}
|
|
58
8
|
function createStaticPathsCode(staticPaths) {
|
|
59
9
|
return JSON.stringify(Array.from(new Set(staticPaths)).sort()).slice(1, -1);
|
|
60
10
|
}
|
|
61
|
-
const injectStatics = async (staticPathsCode,
|
|
11
|
+
const injectStatics = async (staticPathsCode, outDir) => {
|
|
62
12
|
const promises = /* @__PURE__ */ new Set();
|
|
63
13
|
const doReplace = async (path) => {
|
|
64
14
|
const code = await fs.promises.readFile(path, "utf-8");
|
|
65
15
|
let replaced = false;
|
|
66
|
-
const newCode = code.replace(/(['"])
|
|
16
|
+
const newCode = code.replace(/(['"])__QWIK_ROUTER_STATIC_PATHS_ARRAY__\1/g, () => {
|
|
67
17
|
replaced = true;
|
|
68
|
-
return
|
|
18
|
+
return staticPathsCode;
|
|
69
19
|
});
|
|
70
20
|
if (replaced) {
|
|
71
21
|
await fs.promises.writeFile(path, newCode);
|
|
@@ -91,37 +41,37 @@ const injectStatics = async (staticPathsCode, notFoundPathsCode, outDir) => {
|
|
|
91
41
|
};
|
|
92
42
|
async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths, cleanStatic) {
|
|
93
43
|
if (pathName && !pathName.endsWith("/")) {
|
|
94
|
-
pathName
|
|
44
|
+
pathName = ensureSlash(pathName);
|
|
95
45
|
}
|
|
46
|
+
const pathNameBase = pathName || "/";
|
|
96
47
|
const ignorePathnames = /* @__PURE__ */ new Set([
|
|
97
|
-
|
|
98
|
-
|
|
48
|
+
pathNameBase + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/",
|
|
49
|
+
pathNameBase + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/"
|
|
99
50
|
]);
|
|
100
|
-
const staticPaths = new Set(userStaticPaths.map(
|
|
101
|
-
const notFounds = [];
|
|
51
|
+
const staticPaths = new Set(userStaticPaths.map(ensureSlash));
|
|
102
52
|
const loadItem = async (fsDir, fsName, pathname) => {
|
|
103
|
-
pathname =
|
|
53
|
+
pathname = ensureSlash(pathname);
|
|
104
54
|
if (ignorePathnames.has(pathname)) {
|
|
105
55
|
return;
|
|
106
56
|
}
|
|
107
57
|
const fsPath = join(fsDir, fsName);
|
|
108
|
-
if (fsName === "index.html"
|
|
58
|
+
if (fsName === "index.html") {
|
|
109
59
|
if (!staticPaths.has(pathname) && cleanStatic) {
|
|
110
60
|
await fs.promises.unlink(fsPath);
|
|
111
61
|
}
|
|
112
62
|
return;
|
|
113
63
|
}
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
64
|
+
if (LOADER_REGEX.test("/" + fsName)) {
|
|
65
|
+
if (staticPaths.has(pathname)) {
|
|
66
|
+
staticPaths.add(pathname + fsName);
|
|
67
|
+
} else if (cleanStatic) {
|
|
68
|
+
await fs.promises.unlink(fsPath);
|
|
69
|
+
}
|
|
120
70
|
return;
|
|
121
71
|
}
|
|
122
72
|
const stat = await fs.promises.stat(fsPath);
|
|
123
73
|
if (stat.isDirectory()) {
|
|
124
|
-
await loadDir(fsPath, pathname + fsName
|
|
74
|
+
await loadDir(fsPath, ensureSlash(pathname + fsName));
|
|
125
75
|
} else if (stat.isFile()) {
|
|
126
76
|
staticPaths.add(pathname + fsName);
|
|
127
77
|
}
|
|
@@ -133,19 +83,21 @@ async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths,
|
|
|
133
83
|
if (fs.existsSync(clientOutDir)) {
|
|
134
84
|
await loadDir(clientOutDir, pathName);
|
|
135
85
|
}
|
|
136
|
-
const notFoundPathsCode = createNotFoundPathsCode(pathName, notFounds);
|
|
137
86
|
const staticPathsCode = createStaticPathsCode(staticPaths);
|
|
138
|
-
await injectStatics(staticPathsCode,
|
|
87
|
+
await injectStatics(staticPathsCode, serverOutDir);
|
|
139
88
|
}
|
|
140
89
|
|
|
141
90
|
const QWIK_SSG_ENTRY_ID = "@qwik-ssg-entry";
|
|
142
91
|
const QWIK_SSG_ENTRY_RESOLVED = "\0@qwik-ssg-entry";
|
|
92
|
+
const QWIK_SSG_WORKER_ENTRY_ID = "@qwik-ssg-worker-entry";
|
|
93
|
+
const QWIK_SSG_WORKER_ENTRY_RESOLVED = "\0@qwik-ssg-worker-entry";
|
|
143
94
|
function viteAdapter(opts) {
|
|
144
95
|
let qwikRouterPlugin = null;
|
|
145
96
|
let qwikVitePlugin = null;
|
|
146
|
-
let serverOutDir = null;
|
|
147
97
|
let viteCommand;
|
|
98
|
+
let buildAppRan = false;
|
|
148
99
|
const outputEntries = [];
|
|
100
|
+
const ssgOutDirFor = (root) => join(resolve(root), "node_modules", ".cache", `qwik-router-ssg-${process.pid}`);
|
|
149
101
|
const plugin = {
|
|
150
102
|
name: `vite-plugin-qwik-router-ssg-${opts.name}`,
|
|
151
103
|
enforce: "post",
|
|
@@ -158,30 +110,78 @@ function viteAdapter(opts) {
|
|
|
158
110
|
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "production"),
|
|
159
111
|
...config.define
|
|
160
112
|
};
|
|
113
|
+
config.builder ??= {};
|
|
114
|
+
if (opts.ssg !== null) {
|
|
115
|
+
config.environments = {
|
|
116
|
+
...config.environments,
|
|
117
|
+
// Same server externalization as `ssr` (via the router/qwik `configEnvironment` hooks);
|
|
118
|
+
// only the build graph and outDir differ. run-ssg externalizes node_modules deps and
|
|
119
|
+
// resolves them at render time, so native/CJS packages (e.g. a database client) are not
|
|
120
|
+
// force-bundled.
|
|
121
|
+
ssg: {
|
|
122
|
+
consumer: "server",
|
|
123
|
+
build: {
|
|
124
|
+
ssr: true,
|
|
125
|
+
outDir: ssgOutDirFor(config.root ?? process.cwd()),
|
|
126
|
+
emptyOutDir: true,
|
|
127
|
+
// Throwaway output, executed once and deleted — skip minify/sourcemap work.
|
|
128
|
+
minify: false,
|
|
129
|
+
sourcemap: false
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
161
134
|
return config;
|
|
162
135
|
},
|
|
136
|
+
configEnvironment(name, environmentOptions) {
|
|
137
|
+
if (name === "ssg") {
|
|
138
|
+
environmentOptions.build = {
|
|
139
|
+
...environmentOptions.build,
|
|
140
|
+
rollupOptions: {
|
|
141
|
+
...environmentOptions.build?.rollupOptions,
|
|
142
|
+
input: {}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
},
|
|
163
147
|
configResolved(config) {
|
|
164
148
|
viteCommand = config.command;
|
|
165
149
|
qwikRouterPlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik-router");
|
|
166
150
|
if (!qwikRouterPlugin) {
|
|
167
151
|
throw new Error("Missing vite-plugin-qwik-router");
|
|
168
152
|
}
|
|
153
|
+
qwikRouterPlugin.api?._setSsgRoutes?.(opts.ssg?.include, opts.ssg?.exclude);
|
|
169
154
|
qwikVitePlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik");
|
|
170
155
|
if (!qwikVitePlugin) {
|
|
171
156
|
throw new Error("Missing vite-plugin-qwik");
|
|
172
157
|
}
|
|
173
|
-
serverOutDir = config.build.outDir;
|
|
174
158
|
},
|
|
175
159
|
resolveId(id) {
|
|
176
160
|
if (id === QWIK_SSG_ENTRY_ID) {
|
|
177
161
|
return QWIK_SSG_ENTRY_RESOLVED;
|
|
178
162
|
}
|
|
163
|
+
if (id === QWIK_SSG_WORKER_ENTRY_ID) {
|
|
164
|
+
return QWIK_SSG_WORKER_ENTRY_RESOLVED;
|
|
165
|
+
}
|
|
179
166
|
},
|
|
180
167
|
load(id) {
|
|
168
|
+
if (id === QWIK_SSG_WORKER_ENTRY_RESOLVED) {
|
|
169
|
+
const { srcDir } = qwikVitePlugin.api.getOptions();
|
|
170
|
+
return [
|
|
171
|
+
`import render from '${srcDir}/entry.ssr';`,
|
|
172
|
+
`import qwikRouterConfig from '@qwik-router-config';`,
|
|
173
|
+
`import { startWorker } from '@qwik.dev/router/ssg';`,
|
|
174
|
+
// Fire-and-forget (no top-level await): avoids a Rollup inlined-dynamic-import init-order
|
|
175
|
+
// bug on the SSR target. See rollup/rollup#4166.
|
|
176
|
+
`startWorker({ render, qwikRouterConfig }).catch((err) => {`,
|
|
177
|
+
` console.error(err);`,
|
|
178
|
+
` process.exit(1);`,
|
|
179
|
+
`});`
|
|
180
|
+
].join("\n");
|
|
181
|
+
}
|
|
181
182
|
if (id !== QWIK_SSG_ENTRY_RESOLVED) {
|
|
182
183
|
return;
|
|
183
184
|
}
|
|
184
|
-
const { srcDir } = qwikVitePlugin.api.getOptions();
|
|
185
185
|
const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
|
|
186
186
|
const basePathname = qwikRouterPlugin.api.getBasePathname();
|
|
187
187
|
const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0;
|
|
@@ -215,47 +215,43 @@ function viteAdapter(opts) {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
return [
|
|
218
|
-
`import { isMainThread } from 'node:worker_threads';`,
|
|
219
|
-
`import render from '${srcDir}/entry.ssr';`,
|
|
220
218
|
`import qwikRouterConfig from '@qwik-router-config';`,
|
|
221
|
-
`import { runSsg
|
|
219
|
+
`import { runSsg } from '@qwik.dev/router/ssg';`,
|
|
222
220
|
``,
|
|
223
221
|
`const ssgOpts = ${JSON.stringify(ssgOpts)};`,
|
|
224
222
|
``,
|
|
225
223
|
`// Parse --quiet / --debug CLI flags`,
|
|
226
|
-
`const args =
|
|
224
|
+
`const args = process.argv.slice(2);`,
|
|
227
225
|
`if (args.includes('--quiet')) ssgOpts.log = 'quiet';`,
|
|
228
226
|
`if (args.includes('--debug')) ssgOpts.log = 'debug';`,
|
|
229
227
|
``,
|
|
230
|
-
// Fire-and-forget
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
`
|
|
235
|
-
`
|
|
236
|
-
` render,`,
|
|
237
|
-
` qwikRouterConfig,`,
|
|
238
|
-
` workerFilePath: new URL(import.meta.url).href,`,
|
|
239
|
-
` ...ssgOpts,`,
|
|
240
|
-
` })`,
|
|
241
|
-
` : startWorker({ render, qwikRouterConfig });`,
|
|
242
|
-
`ssgRun.catch((err) => {`,
|
|
228
|
+
// Fire-and-forget; see rollup/rollup#4166 above. The worker entry is a sibling file.
|
|
229
|
+
`runSsg({`,
|
|
230
|
+
` qwikRouterConfig,`,
|
|
231
|
+
` workerFilePath: new URL('./run-ssg-worker.js', import.meta.url).href,`,
|
|
232
|
+
` ...ssgOpts,`,
|
|
233
|
+
`}).catch((err) => {`,
|
|
243
234
|
` console.error(err);`,
|
|
244
235
|
` process.exit(1);`,
|
|
245
236
|
`});`
|
|
246
237
|
].join("\n");
|
|
247
238
|
},
|
|
248
239
|
buildStart() {
|
|
249
|
-
if (this.environment.
|
|
240
|
+
if (this.environment.name === "ssg" && viteCommand === "build") {
|
|
250
241
|
this.emitFile({
|
|
251
242
|
id: QWIK_SSG_ENTRY_ID,
|
|
252
243
|
type: "chunk",
|
|
253
244
|
fileName: "run-ssg.js"
|
|
254
245
|
});
|
|
246
|
+
this.emitFile({
|
|
247
|
+
id: QWIK_SSG_WORKER_ENTRY_ID,
|
|
248
|
+
type: "chunk",
|
|
249
|
+
fileName: "run-ssg-worker.js"
|
|
250
|
+
});
|
|
255
251
|
}
|
|
256
252
|
},
|
|
257
253
|
generateBundle(_, bundles) {
|
|
258
|
-
if (this.environment.
|
|
254
|
+
if (this.environment.name === "ssr") {
|
|
259
255
|
outputEntries.length = 0;
|
|
260
256
|
for (const fileName in bundles) {
|
|
261
257
|
const chunk = bundles[fileName];
|
|
@@ -263,77 +259,93 @@ function viteAdapter(opts) {
|
|
|
263
259
|
outputEntries.push(fileName);
|
|
264
260
|
}
|
|
265
261
|
}
|
|
262
|
+
if (opts.ssg !== null && viteCommand === "build" && !buildAppRan) {
|
|
263
|
+
this.warn("Qwik Router SSG was skipped: the `ssr` environment was built directly instead of through the Vite app builder, so no pages were prerendered. Build with the Qwik CLI or `createBuilder(config).buildApp()` (a plain `vite build` does this automatically).");
|
|
264
|
+
}
|
|
266
265
|
}
|
|
267
266
|
},
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const staticPathsFile = join(clientPublicOutDir, "_static-paths.json");
|
|
305
|
-
try {
|
|
306
|
-
const content = await fs.promises.readFile(staticPathsFile, "utf-8");
|
|
307
|
-
staticPaths.push(...JSON.parse(content));
|
|
308
|
-
await fs.promises.unlink(staticPathsFile);
|
|
309
|
-
} catch {
|
|
267
|
+
// Build the deployed server (`ssr`) and the separate `ssg` graph (run-ssg) — two graphs, so
|
|
268
|
+
// prerendered route code never reaches the `ssr` bundle — then render the pages and post-build.
|
|
269
|
+
// (The client builds in its own `vite build`.)
|
|
270
|
+
async buildApp(builder) {
|
|
271
|
+
buildAppRan = true;
|
|
272
|
+
const ssr = builder.environments.ssr;
|
|
273
|
+
if (ssr) {
|
|
274
|
+
await builder.build(ssr);
|
|
275
|
+
}
|
|
276
|
+
const serverOutDir = ssr?.config.build.outDir;
|
|
277
|
+
if (!serverOutDir || !qwikRouterPlugin?.api || !qwikVitePlugin?.api) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const log = builder.config.logger;
|
|
281
|
+
const staticPaths = opts.staticPaths || [];
|
|
282
|
+
const routes = qwikRouterPlugin.api.getRoutes();
|
|
283
|
+
const basePathname = qwikRouterPlugin.api.getBasePathname();
|
|
284
|
+
const clientOutDir = qwikVitePlugin.api.getClientOutDir();
|
|
285
|
+
const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
|
|
286
|
+
const ssgEnv = builder.environments.ssg;
|
|
287
|
+
const ssgOutDir = ssgOutDirFor(builder.config.root);
|
|
288
|
+
if (ssgEnv && clientOutDir && clientPublicOutDir) {
|
|
289
|
+
await builder.build(ssgEnv);
|
|
290
|
+
const runSsgPath = join(ssgOutDir, "run-ssg.js");
|
|
291
|
+
const ssgExitCode = await new Promise((res, reject) => {
|
|
292
|
+
const child = spawn(process.execPath, [
|
|
293
|
+
runSsgPath
|
|
294
|
+
], {
|
|
295
|
+
stdio: [
|
|
296
|
+
"ignore",
|
|
297
|
+
"inherit",
|
|
298
|
+
"inherit"
|
|
299
|
+
],
|
|
300
|
+
env: {
|
|
301
|
+
...process.env,
|
|
302
|
+
NODE_ENV: process.env.NODE_ENV || "production"
|
|
310
303
|
}
|
|
304
|
+
});
|
|
305
|
+
child.on("close", res);
|
|
306
|
+
child.on("error", reject);
|
|
307
|
+
});
|
|
308
|
+
if (ssgExitCode !== 0) {
|
|
309
|
+
throw new Error(`Error while running SSG from "${opts.name}" adapter. At least one path failed to render.`);
|
|
310
|
+
}
|
|
311
|
+
const staticPathsFile = join(clientPublicOutDir, "_static-paths.json");
|
|
312
|
+
try {
|
|
313
|
+
staticPaths.push(...JSON.parse(await readFile(staticPathsFile, "utf-8")));
|
|
314
|
+
await unlink(staticPathsFile);
|
|
315
|
+
} catch {
|
|
316
|
+
}
|
|
317
|
+
if (process.env.QWIK_ROUTER_KEEP_SSG_BUILD) {
|
|
318
|
+
log.warn(`SSG build kept at ${ssgOutDir}`);
|
|
319
|
+
} else {
|
|
320
|
+
await rm(ssgOutDir, {
|
|
321
|
+
recursive: true,
|
|
322
|
+
force: true
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
await postBuild(clientPublicOutDir, serverOutDir, basePathname, staticPaths, !!opts.cleanStaticGenerated);
|
|
327
|
+
if (typeof opts.generate === "function") {
|
|
328
|
+
await opts.generate({
|
|
329
|
+
outputEntries,
|
|
330
|
+
serverOutDir,
|
|
331
|
+
clientOutDir,
|
|
332
|
+
clientPublicOutDir,
|
|
333
|
+
basePathname,
|
|
334
|
+
routes,
|
|
335
|
+
warn: (message) => log.warn(message),
|
|
336
|
+
error: (message) => {
|
|
337
|
+
throw new Error(message);
|
|
311
338
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
outputEntries,
|
|
316
|
-
serverOutDir,
|
|
317
|
-
clientOutDir,
|
|
318
|
-
clientPublicOutDir,
|
|
319
|
-
basePathname,
|
|
320
|
-
routes,
|
|
321
|
-
assetsDir,
|
|
322
|
-
warn: (message) => this.warn(message),
|
|
323
|
-
error: (message) => this.error(message)
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
this.warn(`
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
log.warn(`
|
|
327
342
|
==============================================
|
|
328
343
|
Note: Make sure that you are serving the built files with proper cache headers.
|
|
329
344
|
See https://qwik.dev/docs/deployments/#cache-headers for more information.
|
|
330
345
|
==============================================`);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
346
|
}
|
|
334
347
|
};
|
|
335
348
|
return [
|
|
336
|
-
ssgWorkerImportPlugin(),
|
|
337
349
|
plugin
|
|
338
350
|
];
|
|
339
351
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function toTitleCase(str) {
|
|
2
|
+
return str.replace(/\w\S*/g, (txt) => {
|
|
3
|
+
return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase();
|
|
4
|
+
});
|
|
5
|
+
}
|
|
6
|
+
function addError(ctx, e) {
|
|
7
|
+
ctx.diagnostics.push({
|
|
8
|
+
type: "error",
|
|
9
|
+
message: e ? String(e.stack || e) : "Error"
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function addWarning(ctx, message) {
|
|
13
|
+
ctx.diagnostics.push({
|
|
14
|
+
type: "warn",
|
|
15
|
+
message: String(message)
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function msToString(ms) {
|
|
19
|
+
if (ms < 1) {
|
|
20
|
+
return ms.toFixed(2) + " ms";
|
|
21
|
+
}
|
|
22
|
+
if (ms < 1e3) {
|
|
23
|
+
return ms.toFixed(1) + " ms";
|
|
24
|
+
}
|
|
25
|
+
if (ms < 6e4) {
|
|
26
|
+
return (ms / 1e3).toFixed(1) + " s";
|
|
27
|
+
}
|
|
28
|
+
return (ms / 6e4).toFixed(1) + " m";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { addError as a, addWarning as b, msToString as m, toTitleCase as t };
|
package/lib/chunks/fs.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalize, basename, dirname, relative } from 'node:path';
|
|
2
|
-
import { t as toTitleCase
|
|
2
|
+
import { t as toTitleCase } from './format.mjs';
|
|
3
|
+
import { n as normalizePathname, e as ensureSlash } from './pathname.mjs';
|
|
3
4
|
|
|
4
5
|
function parseRouteIndexName(extlessName) {
|
|
5
6
|
let layoutName = "";
|
|
@@ -56,11 +57,8 @@ function normalizePath(path) {
|
|
|
56
57
|
function getMenuPathname(opts, filePath) {
|
|
57
58
|
let pathname = normalizePath(relative(opts.routesDir, filePath));
|
|
58
59
|
pathname = `/` + normalizePath(dirname(pathname));
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
result += "/";
|
|
62
|
-
}
|
|
63
|
-
return result;
|
|
60
|
+
const result = normalizePathname(pathname, opts.basePathname);
|
|
61
|
+
return ensureSlash(result);
|
|
64
62
|
}
|
|
65
63
|
function createFileId(routesDir, fsPath, explicitFileType) {
|
|
66
64
|
const ids = [];
|
|
@@ -125,8 +123,12 @@ function isServiceWorkerName(extlessName) {
|
|
|
125
123
|
function isEntryName(extlessName) {
|
|
126
124
|
return extlessName === "entry";
|
|
127
125
|
}
|
|
126
|
+
function errorBoundaryName(extlessName) {
|
|
127
|
+
const match = /^(error|404)(?:|!|@.+)$/.exec(extlessName);
|
|
128
|
+
return match ? match[1] : void 0;
|
|
129
|
+
}
|
|
128
130
|
function isErrorName(extlessName) {
|
|
129
|
-
return extlessName
|
|
131
|
+
return errorBoundaryName(extlessName) !== void 0;
|
|
130
132
|
}
|
|
131
133
|
function isGroupedLayoutName(dirName, warn = true) {
|
|
132
134
|
return dirName.startsWith("(") && dirName.endsWith(")");
|
|
@@ -141,4 +143,4 @@ function getPathnameFromDirPath(opts, dirPath) {
|
|
|
141
143
|
return pathname;
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
export { isErrorName as a,
|
|
146
|
+
export { isErrorName as a, isPageModuleExt as b, isModuleExt as c, isMarkdownExt as d, isLayoutModule as e, isEntryName as f, getExtension as g, isMenuFileName as h, isIndexModule as i, isServiceWorkerName as j, normalizePath as k, getPathnameFromDirPath as l, getMenuPathname as m, normalizePathSlash as n, createFileId as o, parseRouteIndexName as p, errorBoundaryName as q, removeExtension as r, isPluginModule as s, isPageExt as t };
|