@qwik.dev/router 2.0.0-beta.28 → 2.0.0-beta.29
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/azure-swa/vite/index.mjs +31 -36
- package/lib/adapters/bun-server/vite/index.mjs +0 -3
- package/lib/adapters/cloud-run/vite/index.mjs +0 -3
- package/lib/adapters/cloudflare-pages/vite/index.mjs +15 -9
- package/lib/adapters/deno-server/vite/index.mjs +7 -5
- package/lib/adapters/netlify-edge/vite/index.mjs +13 -23
- package/lib/adapters/node-server/vite/index.mjs +0 -3
- package/lib/adapters/shared/vite/index.d.ts +1 -7
- package/lib/adapters/shared/vite/index.mjs +164 -136
- package/lib/adapters/ssg/vite/index.mjs +3 -4
- package/lib/adapters/vercel-edge/vite/index.mjs +25 -9
- package/lib/chunks/error-handler.mjs +26 -26
- package/lib/chunks/fs.mjs +28 -138
- package/lib/chunks/http-error.qwik.mjs +27 -0
- package/lib/chunks/not-found-wrapper.qwik.mjs +25 -0
- package/lib/chunks/pathname.mjs +105 -0
- package/lib/chunks/routing.qwik.mjs +592 -216
- package/lib/chunks/system.mjs +328 -0
- package/lib/chunks/use-functions.qwik.mjs +35 -0
- package/lib/chunks/worker-thread.mjs +271 -0
- package/lib/index.d.ts +136 -102
- package/lib/index.qwik.mjs +699 -751
- package/lib/middleware/aws-lambda/index.mjs +7 -1
- package/lib/middleware/azure-swa/index.mjs +7 -2
- package/lib/middleware/bun/index.mjs +20 -5
- package/lib/middleware/cloudflare-pages/index.mjs +8 -2
- package/lib/middleware/deno/index.mjs +19 -5
- package/lib/middleware/netlify-edge/index.mjs +8 -2
- package/lib/middleware/node/index.mjs +10 -14
- package/lib/middleware/request-handler/index.d.ts +82 -12
- package/lib/middleware/request-handler/index.mjs +661 -524
- package/lib/middleware/vercel-edge/index.mjs +8 -2
- package/lib/modules.d.ts +7 -4
- package/lib/ssg/index.d.ts +48 -16
- package/lib/ssg/index.mjs +320 -7
- package/lib/vite/index.d.ts +6 -0
- package/lib/vite/index.mjs +1098 -641
- package/modules.d.ts +7 -4
- package/package.json +4 -4
- package/lib/chunks/format-error.mjs +0 -137
- package/lib/chunks/index.mjs +0 -896
- package/lib/chunks/types.qwik.mjs +0 -22
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { viteAdapter } from '../../shared/vite/index.mjs';
|
|
4
|
-
import '../../../chunks/error-handler.mjs';
|
|
5
4
|
|
|
6
5
|
function azureSwaAdapter(opts = {}) {
|
|
7
6
|
const env = process?.env;
|
|
@@ -13,43 +12,39 @@ function azureSwaAdapter(opts = {}) {
|
|
|
13
12
|
async generate({ outputEntries, serverOutDir, clientPublicOutDir }) {
|
|
14
13
|
const serverPackageJsonPath = join(serverOutDir, "package.json");
|
|
15
14
|
const serverPackageJsonCode = `{"type":"module"}`;
|
|
16
|
-
await fs.promises.mkdir(serverOutDir, {
|
|
15
|
+
await fs.promises.mkdir(serverOutDir, {
|
|
16
|
+
recursive: true
|
|
17
|
+
});
|
|
17
18
|
await fs.promises.writeFile(serverPackageJsonPath, serverPackageJsonCode);
|
|
18
|
-
const azureSwaModulePath = outputEntries.find(
|
|
19
|
-
(entryName) => entryName.indexOf("entry.azure-swa") === 0
|
|
20
|
-
);
|
|
19
|
+
const azureSwaModulePath = outputEntries.find((entryName) => entryName.indexOf("entry.azure-swa") === 0);
|
|
21
20
|
const funcJsonPath = join(serverOutDir, "function.json");
|
|
22
|
-
const funcJson = JSON.stringify(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
null,
|
|
51
|
-
2
|
|
52
|
-
);
|
|
21
|
+
const funcJson = JSON.stringify({
|
|
22
|
+
bindings: [
|
|
23
|
+
{
|
|
24
|
+
authLevel: "anonymous",
|
|
25
|
+
type: "httpTrigger",
|
|
26
|
+
direction: "in",
|
|
27
|
+
name: "req",
|
|
28
|
+
methods: [
|
|
29
|
+
"get",
|
|
30
|
+
"head",
|
|
31
|
+
"post",
|
|
32
|
+
"put",
|
|
33
|
+
"delete",
|
|
34
|
+
"connect",
|
|
35
|
+
"options",
|
|
36
|
+
"trace",
|
|
37
|
+
"patch"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: "http",
|
|
42
|
+
direction: "out",
|
|
43
|
+
name: "$return"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
scriptFile: azureSwaModulePath
|
|
47
|
+
}, null, 2);
|
|
53
48
|
await fs.promises.writeFile(funcJsonPath, funcJson);
|
|
54
49
|
if (!fs.existsSync(join(clientPublicOutDir, "index.html"))) {
|
|
55
50
|
await fs.promises.writeFile(join(clientPublicOutDir, "index.html"), "");
|
|
@@ -2,7 +2,6 @@ import fs from 'node:fs';
|
|
|
2
2
|
import { join, relative } from 'node:path';
|
|
3
3
|
import { n as normalizePathSlash } from '../../../chunks/fs.mjs';
|
|
4
4
|
import { viteAdapter } from '../../shared/vite/index.mjs';
|
|
5
|
-
import '../../../chunks/error-handler.mjs';
|
|
6
5
|
|
|
7
6
|
function cloudflarePagesAdapter(opts = {}) {
|
|
8
7
|
const env = process?.env;
|
|
@@ -15,12 +14,17 @@ function cloudflarePagesAdapter(opts = {}) {
|
|
|
15
14
|
config() {
|
|
16
15
|
return {
|
|
17
16
|
resolve: {
|
|
18
|
-
conditions: [
|
|
17
|
+
conditions: [
|
|
18
|
+
"webworker",
|
|
19
|
+
"worker"
|
|
20
|
+
]
|
|
19
21
|
},
|
|
20
22
|
ssr: {
|
|
21
23
|
target: "webworker",
|
|
22
24
|
noExternal: true,
|
|
23
|
-
external: [
|
|
25
|
+
external: [
|
|
26
|
+
"node:async_hooks"
|
|
27
|
+
]
|
|
24
28
|
},
|
|
25
29
|
build: {
|
|
26
30
|
ssr: true,
|
|
@@ -44,8 +48,13 @@ function cloudflarePagesAdapter(opts = {}) {
|
|
|
44
48
|
}
|
|
45
49
|
const routesJson = {
|
|
46
50
|
version: 1,
|
|
47
|
-
include: [
|
|
48
|
-
|
|
51
|
+
include: [
|
|
52
|
+
basePathname + "*"
|
|
53
|
+
],
|
|
54
|
+
exclude: [
|
|
55
|
+
pathName + "build/*",
|
|
56
|
+
pathName + "assets/*"
|
|
57
|
+
]
|
|
49
58
|
};
|
|
50
59
|
await fs.promises.writeFile(routesJsonPath, JSON.stringify(routesJson, void 0, 2));
|
|
51
60
|
}
|
|
@@ -53,10 +62,7 @@ function cloudflarePagesAdapter(opts = {}) {
|
|
|
53
62
|
const hasWorkerJs = fs.existsSync(workerJsPath);
|
|
54
63
|
if (!hasWorkerJs) {
|
|
55
64
|
const importPath = relative(clientOutDir, join(serverOutDir, "entry.cloudflare-pages"));
|
|
56
|
-
await fs.promises.writeFile(
|
|
57
|
-
workerJsPath,
|
|
58
|
-
`import { fetch } from "${normalizePathSlash(importPath)}"; export default { fetch };`
|
|
59
|
-
);
|
|
65
|
+
await fs.promises.writeFile(workerJsPath, `import { fetch } from "${normalizePathSlash(importPath)}"; export default { fetch };`);
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
});
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { viteAdapter } from '../../shared/vite/index.mjs';
|
|
2
|
-
import 'node:path';
|
|
3
|
-
import 'node:fs';
|
|
4
|
-
import '../../../chunks/error-handler.mjs';
|
|
5
2
|
|
|
6
3
|
function denoServerAdapter(opts = {}) {
|
|
7
4
|
const env = process?.env;
|
|
@@ -13,12 +10,17 @@ function denoServerAdapter(opts = {}) {
|
|
|
13
10
|
config() {
|
|
14
11
|
return {
|
|
15
12
|
resolve: {
|
|
16
|
-
conditions: [
|
|
13
|
+
conditions: [
|
|
14
|
+
"webworker",
|
|
15
|
+
"worker"
|
|
16
|
+
]
|
|
17
17
|
},
|
|
18
18
|
ssr: {
|
|
19
19
|
target: "webworker",
|
|
20
20
|
noExternal: true,
|
|
21
|
-
external: [
|
|
21
|
+
external: [
|
|
22
|
+
"node:async_hooks"
|
|
23
|
+
]
|
|
22
24
|
},
|
|
23
25
|
build: {
|
|
24
26
|
ssr: true,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs, { existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { viteAdapter, getParentDir } from '../../shared/vite/index.mjs';
|
|
4
|
-
import '../../../chunks/error-handler.mjs';
|
|
5
4
|
|
|
6
5
|
function netlifyEdgeAdapter(opts = {}) {
|
|
7
6
|
const env = process?.env;
|
|
@@ -15,12 +14,17 @@ function netlifyEdgeAdapter(opts = {}) {
|
|
|
15
14
|
const outDir = config.build?.outDir || ".netlify/edge-functions/entry.netlify-edge";
|
|
16
15
|
return {
|
|
17
16
|
resolve: {
|
|
18
|
-
conditions: [
|
|
17
|
+
conditions: [
|
|
18
|
+
"webworker",
|
|
19
|
+
"worker"
|
|
20
|
+
]
|
|
19
21
|
},
|
|
20
22
|
ssr: {
|
|
21
23
|
target: "webworker",
|
|
22
24
|
noExternal: true,
|
|
23
|
-
external: [
|
|
25
|
+
external: [
|
|
26
|
+
"node:async_hooks"
|
|
27
|
+
]
|
|
24
28
|
},
|
|
25
29
|
build: {
|
|
26
30
|
ssr: true,
|
|
@@ -43,15 +47,7 @@ function netlifyEdgeAdapter(opts = {}) {
|
|
|
43
47
|
} else if (Array.isArray(opts.excludedPath)) {
|
|
44
48
|
excludedPath.push(...opts.excludedPath);
|
|
45
49
|
} else {
|
|
46
|
-
excludedPath.push(
|
|
47
|
-
"/build/*",
|
|
48
|
-
"/favicon.ico",
|
|
49
|
-
"/robots.txt",
|
|
50
|
-
"/mainifest.json",
|
|
51
|
-
"/~partytown/*",
|
|
52
|
-
"/service-worker.js",
|
|
53
|
-
"/sitemap.xml"
|
|
54
|
-
);
|
|
50
|
+
excludedPath.push("/build/*", "/favicon.ico", "/robots.txt", "/mainifest.json", "/~partytown/*", "/service-worker.js", "/sitemap.xml");
|
|
55
51
|
}
|
|
56
52
|
const netlifyEdgeManifest = {
|
|
57
53
|
functions: [
|
|
@@ -67,19 +63,13 @@ function netlifyEdgeAdapter(opts = {}) {
|
|
|
67
63
|
const jsPath = join(serverOutDir, "entry.netlify-edge.js");
|
|
68
64
|
const mjsPath = join(serverOutDir, "entry.netlify-edge.mjs");
|
|
69
65
|
if (existsSync(mjsPath)) {
|
|
70
|
-
await fs.promises.writeFile(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`export default entry_netlifyEdge;`
|
|
75
|
-
].join("\n")
|
|
76
|
-
);
|
|
66
|
+
await fs.promises.writeFile(jsPath, [
|
|
67
|
+
`import entry_netlifyEdge from './entry.netlify-edge.mjs';`,
|
|
68
|
+
`export default entry_netlifyEdge;`
|
|
69
|
+
].join("\n"));
|
|
77
70
|
}
|
|
78
71
|
const netlifyEdgeFnsDir = getParentDir(serverOutDir, "edge-functions");
|
|
79
|
-
await fs.promises.writeFile(
|
|
80
|
-
join(netlifyEdgeFnsDir, "manifest.json"),
|
|
81
|
-
JSON.stringify(netlifyEdgeManifest, null, 2)
|
|
82
|
-
);
|
|
72
|
+
await fs.promises.writeFile(join(netlifyEdgeFnsDir, "manifest.json"), JSON.stringify(netlifyEdgeManifest, null, 2));
|
|
83
73
|
}
|
|
84
74
|
}
|
|
85
75
|
});
|
|
@@ -74,13 +74,7 @@ export declare interface ServerAdapterOptions {
|
|
|
74
74
|
ssg?: AdapterSSGOptions | null;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/**
|
|
78
|
-
* Implements the SSG after the build is complete. Also provides a `generate(...)` callback that is
|
|
79
|
-
* called after the SSG is complete, which allows for custom post-processing of the complete build
|
|
80
|
-
* results.
|
|
81
|
-
*
|
|
82
|
-
* @public
|
|
83
|
-
*/
|
|
77
|
+
/** @public */
|
|
84
78
|
export declare function viteAdapter(opts: ViteAdapterPluginOptions): Plugin_2<never>;
|
|
85
79
|
|
|
86
80
|
/** @public */
|
|
@@ -2,51 +2,6 @@ import { join, resolve, dirname, basename } from 'node:path';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import { g as getErrorHtml } from '../../../chunks/error-handler.mjs';
|
|
4
4
|
|
|
5
|
-
async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths, cleanStatic) {
|
|
6
|
-
if (pathName && !pathName.endsWith("/")) {
|
|
7
|
-
pathName += "/";
|
|
8
|
-
}
|
|
9
|
-
const ignorePathnames = /* @__PURE__ */ new Set([
|
|
10
|
-
pathName + "/" + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/",
|
|
11
|
-
pathName + "/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/"
|
|
12
|
-
]);
|
|
13
|
-
const staticPaths = new Set(userStaticPaths.map(normalizeTrailingSlash));
|
|
14
|
-
const notFounds = [];
|
|
15
|
-
const loadItem = async (fsDir, fsName, pathname) => {
|
|
16
|
-
pathname = normalizeTrailingSlash(pathname);
|
|
17
|
-
if (ignorePathnames.has(pathname)) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
const fsPath = join(fsDir, fsName);
|
|
21
|
-
if (fsName === "index.html" || fsName === "q-data.json") {
|
|
22
|
-
if (!staticPaths.has(pathname) && cleanStatic) {
|
|
23
|
-
await fs.promises.unlink(fsPath);
|
|
24
|
-
}
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (fsName === "404.html") {
|
|
28
|
-
const notFoundHtml = await fs.promises.readFile(fsPath, "utf-8");
|
|
29
|
-
notFounds.push([pathname, notFoundHtml]);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const stat = await fs.promises.stat(fsPath);
|
|
33
|
-
if (stat.isDirectory()) {
|
|
34
|
-
await loadDir(fsPath, pathname + fsName + "/");
|
|
35
|
-
} else if (stat.isFile()) {
|
|
36
|
-
staticPaths.add(pathname + fsName);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
const loadDir = async (fsDir, pathname) => {
|
|
40
|
-
const itemNames = await fs.promises.readdir(fsDir);
|
|
41
|
-
await Promise.all(itemNames.map((i) => loadItem(fsDir, i, pathname)));
|
|
42
|
-
};
|
|
43
|
-
if (fs.existsSync(clientOutDir)) {
|
|
44
|
-
await loadDir(clientOutDir, pathName);
|
|
45
|
-
}
|
|
46
|
-
const notFoundPathsCode = createNotFoundPathsCode(pathName, notFounds);
|
|
47
|
-
const staticPathsCode = createStaticPathsCode(staticPaths);
|
|
48
|
-
await injectStatics(staticPathsCode, notFoundPathsCode, serverOutDir);
|
|
49
|
-
}
|
|
50
5
|
function normalizeTrailingSlash(pathname) {
|
|
51
6
|
if (!pathname.endsWith("/")) {
|
|
52
7
|
return pathname + "/";
|
|
@@ -71,7 +26,10 @@ function createNotFoundPathsCode(basePathname, notFounds) {
|
|
|
71
26
|
});
|
|
72
27
|
if (!notFounds.some((r) => r[0] === basePathname)) {
|
|
73
28
|
const html = getErrorHtml(404, "Resource Not Found");
|
|
74
|
-
notFounds.push([
|
|
29
|
+
notFounds.push([
|
|
30
|
+
basePathname,
|
|
31
|
+
html
|
|
32
|
+
]);
|
|
75
33
|
}
|
|
76
34
|
return JSON.stringify(notFounds, null, 2).slice(1, -1);
|
|
77
35
|
}
|
|
@@ -83,19 +41,18 @@ const injectStatics = async (staticPathsCode, notFoundPathsCode, outDir) => {
|
|
|
83
41
|
const doReplace = async (path) => {
|
|
84
42
|
const code = await fs.promises.readFile(path, "utf-8");
|
|
85
43
|
let replaced = false;
|
|
86
|
-
const newCode = code.replace(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return type === "STATIC_PATHS" ? staticPathsCode : notFoundPathsCode;
|
|
91
|
-
}
|
|
92
|
-
);
|
|
44
|
+
const newCode = code.replace(/(['"])__QWIK_ROUTER_(STATIC_PATHS|NOT_FOUND)_ARRAY__\1/g, (_, _quote, type) => {
|
|
45
|
+
replaced = true;
|
|
46
|
+
return type === "STATIC_PATHS" ? staticPathsCode : notFoundPathsCode;
|
|
47
|
+
});
|
|
93
48
|
if (replaced) {
|
|
94
49
|
await fs.promises.writeFile(path, newCode);
|
|
95
50
|
}
|
|
96
51
|
};
|
|
97
52
|
const walk = async (dir) => {
|
|
98
|
-
const entries = await fs.promises.readdir(dir, {
|
|
53
|
+
const entries = await fs.promises.readdir(dir, {
|
|
54
|
+
withFileTypes: true
|
|
55
|
+
});
|
|
99
56
|
for (const entry of entries) {
|
|
100
57
|
if (entry.isDirectory()) {
|
|
101
58
|
await walk(join(dir, entry.name));
|
|
@@ -110,13 +67,61 @@ const injectStatics = async (staticPathsCode, notFoundPathsCode, outDir) => {
|
|
|
110
67
|
await walk(outDir);
|
|
111
68
|
await Promise.all(promises);
|
|
112
69
|
};
|
|
70
|
+
async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths, cleanStatic) {
|
|
71
|
+
if (pathName && !pathName.endsWith("/")) {
|
|
72
|
+
pathName += "/";
|
|
73
|
+
}
|
|
74
|
+
const ignorePathnames = /* @__PURE__ */ new Set([
|
|
75
|
+
pathName + "/" + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/",
|
|
76
|
+
pathName + "/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/"
|
|
77
|
+
]);
|
|
78
|
+
const staticPaths = new Set(userStaticPaths.map(normalizeTrailingSlash));
|
|
79
|
+
const notFounds = [];
|
|
80
|
+
const loadItem = async (fsDir, fsName, pathname) => {
|
|
81
|
+
pathname = normalizeTrailingSlash(pathname);
|
|
82
|
+
if (ignorePathnames.has(pathname)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const fsPath = join(fsDir, fsName);
|
|
86
|
+
if (fsName === "index.html" || fsName === "q-data.json") {
|
|
87
|
+
if (!staticPaths.has(pathname) && cleanStatic) {
|
|
88
|
+
await fs.promises.unlink(fsPath);
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (fsName === "404.html") {
|
|
93
|
+
const notFoundHtml = await fs.promises.readFile(fsPath, "utf-8");
|
|
94
|
+
notFounds.push([
|
|
95
|
+
pathname,
|
|
96
|
+
notFoundHtml
|
|
97
|
+
]);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const stat = await fs.promises.stat(fsPath);
|
|
101
|
+
if (stat.isDirectory()) {
|
|
102
|
+
await loadDir(fsPath, pathname + fsName + "/");
|
|
103
|
+
} else if (stat.isFile()) {
|
|
104
|
+
staticPaths.add(pathname + fsName);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const loadDir = async (fsDir, pathname) => {
|
|
108
|
+
const itemNames = await fs.promises.readdir(fsDir);
|
|
109
|
+
await Promise.all(itemNames.map((i) => loadItem(fsDir, i, pathname)));
|
|
110
|
+
};
|
|
111
|
+
if (fs.existsSync(clientOutDir)) {
|
|
112
|
+
await loadDir(clientOutDir, pathName);
|
|
113
|
+
}
|
|
114
|
+
const notFoundPathsCode = createNotFoundPathsCode(pathName, notFounds);
|
|
115
|
+
const staticPathsCode = createStaticPathsCode(staticPaths);
|
|
116
|
+
await injectStatics(staticPathsCode, notFoundPathsCode, serverOutDir);
|
|
117
|
+
}
|
|
113
118
|
|
|
119
|
+
const QWIK_SSG_ENTRY_ID = "@qwik-ssg-entry";
|
|
120
|
+
const QWIK_SSG_ENTRY_RESOLVED = "\0@qwik-ssg-entry";
|
|
114
121
|
function viteAdapter(opts) {
|
|
115
122
|
let qwikRouterPlugin = null;
|
|
116
123
|
let qwikVitePlugin = null;
|
|
117
124
|
let serverOutDir = null;
|
|
118
|
-
let renderModulePath = null;
|
|
119
|
-
let qwikRouterConfigModulePath = null;
|
|
120
125
|
let viteCommand;
|
|
121
126
|
const outputEntries = [];
|
|
122
127
|
const plugin = {
|
|
@@ -135,36 +140,87 @@ function viteAdapter(opts) {
|
|
|
135
140
|
},
|
|
136
141
|
configResolved(config) {
|
|
137
142
|
viteCommand = config.command;
|
|
138
|
-
qwikRouterPlugin = config.plugins.find(
|
|
139
|
-
(p) => p.name === "vite-plugin-qwik-router"
|
|
140
|
-
);
|
|
143
|
+
qwikRouterPlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik-router");
|
|
141
144
|
if (!qwikRouterPlugin) {
|
|
142
145
|
throw new Error("Missing vite-plugin-qwik-router");
|
|
143
146
|
}
|
|
144
|
-
qwikVitePlugin = config.plugins.find(
|
|
145
|
-
(p) => p.name === "vite-plugin-qwik"
|
|
146
|
-
);
|
|
147
|
+
qwikVitePlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik");
|
|
147
148
|
if (!qwikVitePlugin) {
|
|
148
149
|
throw new Error("Missing vite-plugin-qwik");
|
|
149
150
|
}
|
|
150
151
|
serverOutDir = config.build.outDir;
|
|
151
152
|
},
|
|
152
|
-
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
153
|
+
resolveId(id) {
|
|
154
|
+
if (id === QWIK_SSG_ENTRY_ID) {
|
|
155
|
+
return QWIK_SSG_ENTRY_RESOLVED;
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
load(id) {
|
|
159
|
+
if (id !== QWIK_SSG_ENTRY_RESOLVED) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const { srcDir } = qwikVitePlugin.api.getOptions();
|
|
163
|
+
const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
|
|
164
|
+
const basePathname = qwikRouterPlugin.api.getBasePathname();
|
|
165
|
+
const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0;
|
|
166
|
+
let ssgOrigin = opts.ssg?.origin ?? opts.origin;
|
|
167
|
+
if (!ssgOrigin) {
|
|
168
|
+
ssgOrigin = `https://yoursite.qwik.dev`;
|
|
169
|
+
}
|
|
170
|
+
if (ssgOrigin.length > 0 && !/:\/\//.test(ssgOrigin)) {
|
|
171
|
+
ssgOrigin = `https://${ssgOrigin}`;
|
|
172
|
+
}
|
|
173
|
+
if (ssgOrigin.startsWith("//")) {
|
|
174
|
+
ssgOrigin = `https:${ssgOrigin}`;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
ssgOrigin = new URL(ssgOrigin).origin;
|
|
178
|
+
} catch {
|
|
179
|
+
this.warn(`Invalid "origin" option: "${ssgOrigin}". Using default origin: "https://yoursite.qwik.dev"`);
|
|
180
|
+
ssgOrigin = `https://yoursite.qwik.dev`;
|
|
181
|
+
}
|
|
182
|
+
const ssgOpts = {
|
|
183
|
+
origin: ssgOrigin,
|
|
184
|
+
outDir: clientPublicOutDir,
|
|
185
|
+
basePathname,
|
|
186
|
+
rootDir,
|
|
187
|
+
...opts.ssg,
|
|
188
|
+
maxWorkers: opts.maxWorkers
|
|
189
|
+
};
|
|
190
|
+
for (const key of Object.keys(ssgOpts)) {
|
|
191
|
+
if (ssgOpts[key] === void 0) {
|
|
192
|
+
delete ssgOpts[key];
|
|
166
193
|
}
|
|
167
194
|
}
|
|
195
|
+
return [
|
|
196
|
+
`import { isMainThread } from 'node:worker_threads';`,
|
|
197
|
+
`import render from '${srcDir}/entry.ssr';`,
|
|
198
|
+
`import qwikRouterConfig from '@qwik-router-config';`,
|
|
199
|
+
``,
|
|
200
|
+
`const ssgOpts = ${JSON.stringify(ssgOpts)};`,
|
|
201
|
+
``,
|
|
202
|
+
`if (isMainThread) {`,
|
|
203
|
+
` const { runSsg } = await import('@qwik.dev/router/ssg');`,
|
|
204
|
+
` await runSsg({`,
|
|
205
|
+
` render,`,
|
|
206
|
+
` qwikRouterConfig,`,
|
|
207
|
+
` workerFilePath: new URL(import.meta.url).href,`,
|
|
208
|
+
` ...ssgOpts,`,
|
|
209
|
+
` });`,
|
|
210
|
+
`} else {`,
|
|
211
|
+
` const { startWorker } = await import('@qwik.dev/router/ssg');`,
|
|
212
|
+
` await startWorker({ render, qwikRouterConfig });`,
|
|
213
|
+
`}`
|
|
214
|
+
].join("\n");
|
|
215
|
+
},
|
|
216
|
+
buildStart() {
|
|
217
|
+
if (this.environment.config.consumer === "server" && opts.ssg !== null && viteCommand === "build" && serverOutDir) {
|
|
218
|
+
this.emitFile({
|
|
219
|
+
id: QWIK_SSG_ENTRY_ID,
|
|
220
|
+
type: "chunk",
|
|
221
|
+
fileName: "run-ssg.js"
|
|
222
|
+
});
|
|
223
|
+
}
|
|
168
224
|
},
|
|
169
225
|
generateBundle(_, bundles) {
|
|
170
226
|
if (this.environment.config.consumer === "server") {
|
|
@@ -173,11 +229,6 @@ function viteAdapter(opts) {
|
|
|
173
229
|
const chunk = bundles[fileName];
|
|
174
230
|
if (chunk.type === "chunk" && chunk.isEntry) {
|
|
175
231
|
outputEntries.push(fileName);
|
|
176
|
-
if (chunk.name === "entry.ssr") {
|
|
177
|
-
renderModulePath = join(serverOutDir, fileName);
|
|
178
|
-
} else if (chunk.name === "@qwik-router-config") {
|
|
179
|
-
qwikRouterConfigModulePath = join(serverOutDir, fileName);
|
|
180
|
-
}
|
|
181
232
|
}
|
|
182
233
|
}
|
|
183
234
|
}
|
|
@@ -192,54 +243,41 @@ function viteAdapter(opts) {
|
|
|
192
243
|
const clientOutDir = qwikVitePlugin.api.getClientOutDir();
|
|
193
244
|
const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
|
|
194
245
|
const assetsDir = qwikVitePlugin.api.getAssetsDir();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
246
|
+
if (opts.ssg !== null && clientOutDir && clientPublicOutDir) {
|
|
247
|
+
const runSsgPath = join(serverOutDir, "run-ssg.js");
|
|
248
|
+
const { spawn } = await import('node:child_process');
|
|
249
|
+
const ssgExitCode = await new Promise((resolve2, reject) => {
|
|
250
|
+
const child = spawn(process.execPath, [
|
|
251
|
+
runSsgPath
|
|
252
|
+
], {
|
|
253
|
+
stdio: [
|
|
254
|
+
"ignore",
|
|
255
|
+
"inherit",
|
|
256
|
+
"inherit"
|
|
257
|
+
],
|
|
258
|
+
env: {
|
|
259
|
+
...process.env,
|
|
260
|
+
NODE_ENV: process.env.NODE_ENV || "production"
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
child.on("close", resolve2);
|
|
264
|
+
child.on("error", reject);
|
|
265
|
+
});
|
|
266
|
+
if (ssgExitCode !== 0) {
|
|
267
|
+
const err = new Error(`Error while running SSG from "${opts.name}" adapter. At least one path failed to render.`);
|
|
268
|
+
err.stack = void 0;
|
|
269
|
+
this.error(err);
|
|
206
270
|
}
|
|
271
|
+
const fs = await import('node:fs');
|
|
272
|
+
const staticPathsFile = join(clientPublicOutDir, "_static-paths.json");
|
|
207
273
|
try {
|
|
208
|
-
|
|
274
|
+
const content = await fs.promises.readFile(staticPathsFile, "utf-8");
|
|
275
|
+
staticPaths.push(...JSON.parse(content));
|
|
276
|
+
await fs.promises.unlink(staticPathsFile);
|
|
209
277
|
} catch {
|
|
210
|
-
this.warn(
|
|
211
|
-
`Invalid "origin" option: "${ssgOrigin}". Using default origin: "https://yoursite.qwik.dev"`
|
|
212
|
-
);
|
|
213
|
-
ssgOrigin = `https://yoursite.qwik.dev`;
|
|
214
278
|
}
|
|
215
|
-
const staticGenerate = await import('../../../ssg/index.mjs');
|
|
216
|
-
const generateOpts = {
|
|
217
|
-
maxWorkers: opts.maxWorkers,
|
|
218
|
-
basePathname,
|
|
219
|
-
outDir: clientPublicOutDir,
|
|
220
|
-
rootDir,
|
|
221
|
-
...opts.ssg,
|
|
222
|
-
origin: ssgOrigin,
|
|
223
|
-
renderModulePath,
|
|
224
|
-
qwikRouterConfigModulePath
|
|
225
|
-
};
|
|
226
|
-
const staticGenerateResult = await staticGenerate.generate(generateOpts);
|
|
227
|
-
if (staticGenerateResult.errors > 0) {
|
|
228
|
-
const err = new Error(
|
|
229
|
-
`Error while running SSG from "${opts.name}" adapter. At least one path failed to render.`
|
|
230
|
-
);
|
|
231
|
-
err.stack = void 0;
|
|
232
|
-
this.error(err);
|
|
233
|
-
}
|
|
234
|
-
staticPaths.push(...staticGenerateResult.staticPaths);
|
|
235
279
|
}
|
|
236
|
-
await postBuild(
|
|
237
|
-
clientPublicOutDir,
|
|
238
|
-
serverOutDir,
|
|
239
|
-
assetsDir ? join(basePathname, assetsDir) : basePathname,
|
|
240
|
-
staticPaths,
|
|
241
|
-
!!opts.cleanStaticGenerated
|
|
242
|
-
);
|
|
280
|
+
await postBuild(clientPublicOutDir, serverOutDir, assetsDir ? join(basePathname, assetsDir) : basePathname, staticPaths, !!opts.cleanStaticGenerated);
|
|
243
281
|
if (typeof opts.generate === "function") {
|
|
244
282
|
await opts.generate({
|
|
245
283
|
outputEntries,
|
|
@@ -253,21 +291,11 @@ function viteAdapter(opts) {
|
|
|
253
291
|
error: (message) => this.error(message)
|
|
254
292
|
});
|
|
255
293
|
}
|
|
256
|
-
this.warn(
|
|
257
|
-
`
|
|
294
|
+
this.warn(`
|
|
258
295
|
==============================================
|
|
259
296
|
Note: Make sure that you are serving the built files with proper cache headers.
|
|
260
297
|
See https://qwik.dev/docs/deployments/#cache-headers for more information.
|
|
261
|
-
==============================================`
|
|
262
|
-
);
|
|
263
|
-
if (opts.ssg !== null) {
|
|
264
|
-
setTimeout(() => {
|
|
265
|
-
console.warn(
|
|
266
|
-
"SSG seems to be hanging after completion, forcing process to exit. Everything is likely fine."
|
|
267
|
-
);
|
|
268
|
-
process.exit(0);
|
|
269
|
-
}, 5e3).unref();
|
|
270
|
-
}
|
|
298
|
+
==============================================`);
|
|
271
299
|
}
|
|
272
300
|
}
|
|
273
301
|
}
|