@aklinker1/aframe 0.5.0 → 1.0.1
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/README.md +2 -2
- package/package.json +8 -4
- package/src/client/server.ts +25 -20
- package/src/config.ts +15 -8
- package/src/dev-server.ts +11 -14
- package/src/env.d.ts +5 -3
- package/src/index.ts +115 -33
- package/src/{prerenderer.ts → prerender.ts} +3 -4
- package/src/server-entry.ts +0 -6
- package/src/virtual-modules.d.ts +0 -4
package/README.md
CHANGED
|
@@ -28,8 +28,8 @@ export default defineConfig({
|
|
|
28
28
|
},
|
|
29
29
|
// List of routes to pre-render.
|
|
30
30
|
prerenderedRoutes: ["/"],
|
|
31
|
-
//
|
|
32
|
-
|
|
31
|
+
// Configure how prerendering works, or set to `false` to disable
|
|
32
|
+
prerender: {
|
|
33
33
|
// ...
|
|
34
34
|
},
|
|
35
35
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aklinker1/aframe",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"packageManager": "bun@1.2
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"packageManager": "bun@1.3.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"exports": {
|
|
@@ -21,11 +21,10 @@
|
|
|
21
21
|
"check": "check",
|
|
22
22
|
"aframe": "bun --silent bin/aframe.ts",
|
|
23
23
|
"dev": "bun aframe demo",
|
|
24
|
-
"build": "bun aframe build demo",
|
|
24
|
+
"build": "bun aframe build demo && bun run demo/post-build.js",
|
|
25
25
|
"preview": "bun --cwd demo/.output --env-file ../.env server-entry.js",
|
|
26
26
|
"release": "bun run scripts/release.ts"
|
|
27
27
|
},
|
|
28
|
-
"dependencies": {},
|
|
29
28
|
"devDependencies": {
|
|
30
29
|
"@aklinker1/check": "^1.4.5",
|
|
31
30
|
"@types/bun": "latest",
|
|
@@ -39,5 +38,10 @@
|
|
|
39
38
|
"peerDependencies": {
|
|
40
39
|
"vite": "*",
|
|
41
40
|
"puppeteer": "*"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"puppeteer": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
}
|
package/src/client/server.ts
CHANGED
|
@@ -6,8 +6,8 @@ export interface AframeServer {
|
|
|
6
6
|
listen(port: number): void | never;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const staticPathsFile = join(
|
|
10
|
-
const publicDir =
|
|
9
|
+
const staticPathsFile = join(aframe.rootDir, "static.json");
|
|
10
|
+
const publicDir = aframe.publicDir;
|
|
11
11
|
|
|
12
12
|
let staticPaths: Record<string, { cacheable: boolean; path: string }> = {};
|
|
13
13
|
try {
|
|
@@ -29,7 +29,7 @@ export function fetchStatic(options?: {
|
|
|
29
29
|
|
|
30
30
|
// Fetch file on disk
|
|
31
31
|
if (staticPaths[path]) {
|
|
32
|
-
const filePath = join(
|
|
32
|
+
const filePath = join(aframe.rootDir, staticPaths[path].path);
|
|
33
33
|
const file = Bun.file(filePath);
|
|
34
34
|
const gzFile = Bun.file(filePath + ".gz");
|
|
35
35
|
|
|
@@ -45,35 +45,40 @@ export function fetchStatic(options?: {
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// If the path is asking for a file (e.g., it has an extension), return a
|
|
49
|
+
// 404 if it wasn't in the static list
|
|
48
50
|
const ext = extname(basename(path));
|
|
49
51
|
if (ext) {
|
|
50
52
|
return new Response(undefined, { status: 404 });
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
headers: {
|
|
59
|
-
"Content-Type": file.type,
|
|
60
|
-
"Content-Encoding": "gzip",
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
return new Response(
|
|
65
|
-
`<html>
|
|
55
|
+
// During development, render a fallback HTML page since Vite should handle
|
|
56
|
+
// all these routes before proxying the request to the server.
|
|
57
|
+
if (aframe.command === "serve") {
|
|
58
|
+
return new Response(
|
|
59
|
+
`<html>
|
|
66
60
|
<body>
|
|
67
61
|
This is a placeholder for your root <code>index.html</code> file during development.
|
|
68
62
|
<br/>
|
|
69
63
|
In production (or via the app's dev server), this path will fallback on the root <code>index.html</code>.
|
|
70
64
|
</body>
|
|
71
65
|
</html>`,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
{
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "text/html",
|
|
69
|
+
},
|
|
75
70
|
},
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Fallback to public/index.html file
|
|
75
|
+
const file = Bun.file(join(publicDir, "index.html"));
|
|
76
|
+
const gzFile = Bun.file(join(publicDir, "index.html.gz"));
|
|
77
|
+
return new Response(gzFile.stream(), {
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": file.type,
|
|
80
|
+
"Content-Encoding": "gzip",
|
|
76
81
|
},
|
|
77
|
-
);
|
|
82
|
+
});
|
|
78
83
|
};
|
|
79
84
|
}
|
package/src/config.ts
CHANGED
|
@@ -2,6 +2,10 @@ import * as vite from "vite";
|
|
|
2
2
|
import { resolve, join, relative } from "node:path/posix";
|
|
3
3
|
import type { LaunchOptions } from "puppeteer";
|
|
4
4
|
|
|
5
|
+
export type AframeHooks = {
|
|
6
|
+
afterServerBuild?: (config: ResolvedConfig) => Promise<void> | void;
|
|
7
|
+
};
|
|
8
|
+
|
|
5
9
|
export type UserConfig = {
|
|
6
10
|
vite?: vite.UserConfigExport;
|
|
7
11
|
/**
|
|
@@ -10,12 +14,13 @@ export type UserConfig = {
|
|
|
10
14
|
*/
|
|
11
15
|
proxyPaths?: string[];
|
|
12
16
|
prerenderedRoutes?: string[];
|
|
13
|
-
|
|
17
|
+
prerender?: PrerenderConfig | false;
|
|
14
18
|
appPort?: number;
|
|
15
19
|
serverPort?: number;
|
|
20
|
+
hooks?: AframeHooks;
|
|
16
21
|
};
|
|
17
22
|
|
|
18
|
-
export type
|
|
23
|
+
export type PrerenderConfig = {
|
|
19
24
|
/** Wait for an selector`document.querySelector` to be in the DOM before grabbing the HTML. */
|
|
20
25
|
waitForSelector?: string;
|
|
21
26
|
/** When `waitForSelector` is set, also wait for the element to be visible before grabbing the HTML. */
|
|
@@ -33,11 +38,11 @@ export type PrerendererConfig = {
|
|
|
33
38
|
|
|
34
39
|
export type ResolvedConfig = {
|
|
35
40
|
rootDir: string;
|
|
41
|
+
packageJsonPath: string;
|
|
36
42
|
appDir: string;
|
|
37
43
|
publicDir: string;
|
|
38
44
|
serverDir: string;
|
|
39
45
|
serverModule: string;
|
|
40
|
-
serverEntry: string;
|
|
41
46
|
prerenderedDir: string;
|
|
42
47
|
proxyPaths: string[];
|
|
43
48
|
outDir: string;
|
|
@@ -47,7 +52,8 @@ export type ResolvedConfig = {
|
|
|
47
52
|
serverPort: number;
|
|
48
53
|
vite: vite.InlineConfig;
|
|
49
54
|
prerenderedRoutes: string[];
|
|
50
|
-
|
|
55
|
+
prerender: PrerenderConfig | false;
|
|
56
|
+
hooks: AframeHooks | undefined;
|
|
51
57
|
};
|
|
52
58
|
|
|
53
59
|
export function defineConfig(config: UserConfig): UserConfig {
|
|
@@ -60,14 +66,14 @@ export async function resolveConfig(
|
|
|
60
66
|
mode: string,
|
|
61
67
|
): Promise<ResolvedConfig> {
|
|
62
68
|
const rootDir = root ? resolve(root) : process.cwd();
|
|
69
|
+
const packageJsonPath = join(rootDir, "package.json");
|
|
63
70
|
const appDir = join(rootDir, "app");
|
|
64
71
|
const serverDir = join(rootDir, "server");
|
|
65
72
|
const serverModule = join(serverDir, "main.ts");
|
|
66
|
-
const serverEntry = join(import.meta.dir, "server-entry.ts");
|
|
67
73
|
const publicDir = join(rootDir, "public");
|
|
68
74
|
const outDir = join(rootDir, ".output");
|
|
69
75
|
const appOutDir = join(outDir, "public");
|
|
70
|
-
const serverOutDir = outDir;
|
|
76
|
+
const serverOutDir = join(outDir, "server");
|
|
71
77
|
const prerenderedDir = join(outDir, "prerendered");
|
|
72
78
|
|
|
73
79
|
const configFile = join(rootDir, "aframe.config"); // No file extension to resolve any JS/TS file
|
|
@@ -129,11 +135,11 @@ export async function resolveConfig(
|
|
|
129
135
|
|
|
130
136
|
return {
|
|
131
137
|
rootDir,
|
|
138
|
+
packageJsonPath,
|
|
132
139
|
appDir,
|
|
133
140
|
publicDir,
|
|
134
141
|
serverDir,
|
|
135
142
|
serverModule,
|
|
136
|
-
serverEntry,
|
|
137
143
|
outDir,
|
|
138
144
|
serverOutDir,
|
|
139
145
|
appOutDir,
|
|
@@ -144,6 +150,7 @@ export async function resolveConfig(
|
|
|
144
150
|
|
|
145
151
|
prerenderedRoutes: userConfig.prerenderedRoutes ?? ["/"],
|
|
146
152
|
vite: viteConfig,
|
|
147
|
-
|
|
153
|
+
prerender: userConfig.prerender ?? {},
|
|
154
|
+
hooks: userConfig.hooks,
|
|
148
155
|
};
|
|
149
156
|
}
|
package/src/dev-server.ts
CHANGED
|
@@ -11,21 +11,18 @@ export async function createServer(
|
|
|
11
11
|
|
|
12
12
|
let serverProcess: Subprocess | undefined;
|
|
13
13
|
const startServer = () => {
|
|
14
|
-
const js =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const js = `globalThis.aframe = {
|
|
15
|
+
command: "serve",
|
|
16
|
+
rootDir: "${config.rootDir}",
|
|
17
|
+
publicDir: "${config.publicDir}",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const { default: server } = await import('${config.serverModule}');
|
|
21
|
+
|
|
22
|
+
server.listen(${config.serverPort});
|
|
23
|
+
`;
|
|
18
24
|
return Bun.spawn({
|
|
19
|
-
cmd: [
|
|
20
|
-
"bun",
|
|
21
|
-
"--watch",
|
|
22
|
-
"--define",
|
|
23
|
-
`import.meta.publicDir:"${config.publicDir}"`,
|
|
24
|
-
"--define",
|
|
25
|
-
`import.meta.command:"serve"`,
|
|
26
|
-
"--eval",
|
|
27
|
-
js,
|
|
28
|
-
],
|
|
25
|
+
cmd: ["bun", "--watch", "--eval", js],
|
|
29
26
|
stdio: ["inherit", "inherit", "inherit"],
|
|
30
27
|
cwd: config.rootDir,
|
|
31
28
|
});
|
package/src/env.d.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
createReadStream,
|
|
3
|
+
createWriteStream,
|
|
4
|
+
lstatSync,
|
|
5
|
+
type CopyOptions,
|
|
6
|
+
} from "node:fs";
|
|
7
|
+
import { cp, mkdir, readdir, rm, writeFile } from "node:fs/promises";
|
|
4
8
|
import { join, relative } from "node:path/posix";
|
|
5
9
|
import * as vite from "vite";
|
|
6
|
-
import { BLUE, BOLD, CYAN, DIM, GREEN, MAGENTA, RESET } from "./color";
|
|
10
|
+
import { BLUE, BOLD, CYAN, DIM, GREEN, MAGENTA, RESET, YELLOW } from "./color";
|
|
7
11
|
import type { ResolvedConfig } from "./config";
|
|
8
12
|
import { createTimer } from "./timer";
|
|
9
|
-
import { prerenderPages, type PrerenderedRoute } from "./
|
|
13
|
+
import { prerenderPages, type PrerenderedRoute } from "./prerender";
|
|
10
14
|
import { createGzip } from "node:zlib";
|
|
11
15
|
import { pipeline } from "node:stream/promises";
|
|
12
16
|
|
|
@@ -44,7 +48,7 @@ export async function build(config: ResolvedConfig) {
|
|
|
44
48
|
|
|
45
49
|
await gzipFiles(config, allAbsoluteAppFiles);
|
|
46
50
|
|
|
47
|
-
const staticRoutesFile = join(config.
|
|
51
|
+
const staticRoutesFile = join(config.outDir, "static.json");
|
|
48
52
|
let staticRoutes = [
|
|
49
53
|
...Array.from(bundledAppFiles)
|
|
50
54
|
.filter((path) => path !== "index.html")
|
|
@@ -64,26 +68,14 @@ export async function build(config: ResolvedConfig) {
|
|
|
64
68
|
console.log();
|
|
65
69
|
|
|
66
70
|
const serverTimer = createTimer();
|
|
67
|
-
console.log(
|
|
68
|
-
|
|
69
|
-
);
|
|
70
|
-
await Bun.build({
|
|
71
|
-
outdir: config.serverOutDir,
|
|
72
|
-
sourcemap: "external",
|
|
73
|
-
entrypoints: [config.serverEntry],
|
|
74
|
-
target: "bun",
|
|
75
|
-
define: {
|
|
76
|
-
"import.meta.command": `"build"`,
|
|
77
|
-
},
|
|
78
|
-
plugins: [aframeServerMainBunPlugin(config)],
|
|
79
|
-
throw: true,
|
|
80
|
-
});
|
|
71
|
+
console.log(`${BOLD}${CYAN}ℹ${RESET} Building ${CYAN}./server${RESET}`);
|
|
72
|
+
await buildServer(config);
|
|
81
73
|
console.log(`${GREEN}✔${RESET} Built in ${serverTimer()}`);
|
|
82
74
|
|
|
83
75
|
console.log();
|
|
84
76
|
|
|
85
77
|
let prerendered: PrerenderedRoute[] = [];
|
|
86
|
-
if (config.
|
|
78
|
+
if (config.prerender !== false) {
|
|
87
79
|
const prerenderTimer = createTimer();
|
|
88
80
|
console.log(
|
|
89
81
|
`${BOLD}${CYAN}ℹ${RESET} Prerendering...\n` +
|
|
@@ -94,7 +86,7 @@ export async function build(config: ResolvedConfig) {
|
|
|
94
86
|
prerendered = await prerenderPages(config);
|
|
95
87
|
console.log(`${GREEN}✔${RESET} Prerendered in ${prerenderTimer()}`);
|
|
96
88
|
} else {
|
|
97
|
-
console.log(`${DIM}${BOLD}→${RESET} Pre-
|
|
89
|
+
console.log(`${DIM}${BOLD}→${RESET} Pre-render disabled`);
|
|
98
90
|
}
|
|
99
91
|
|
|
100
92
|
await gzipFiles(
|
|
@@ -118,10 +110,8 @@ export async function build(config: ResolvedConfig) {
|
|
|
118
110
|
console.log(`${GREEN}✔${RESET} Application built in ${buildTimer()}`);
|
|
119
111
|
const relativeOutDir = `${relative(config.rootDir, config.outDir)}/`;
|
|
120
112
|
const files = (
|
|
121
|
-
await
|
|
113
|
+
await listDirFiles(config.outDir, (path) => !path.includes("node_modules"))
|
|
122
114
|
)
|
|
123
|
-
.filter((entry) => entry.isFile())
|
|
124
|
-
.map((entry) => join(entry.parentPath, entry.name))
|
|
125
115
|
.toSorted()
|
|
126
116
|
.map((file): [file: string, size: number] => [
|
|
127
117
|
relative(config.outDir, file),
|
|
@@ -142,21 +132,90 @@ export async function build(config: ResolvedConfig) {
|
|
|
142
132
|
);
|
|
143
133
|
console.log(`${CYAN}Σ Total size:${RESET} ${prettyBytes(totalSize)}`);
|
|
144
134
|
console.log();
|
|
135
|
+
|
|
136
|
+
console.log(
|
|
137
|
+
`To preview production build, run:
|
|
138
|
+
|
|
139
|
+
${GREEN}bun run ${relative(process.cwd(), config.outDir)}/server-entry.ts${RESET}
|
|
140
|
+
`,
|
|
141
|
+
);
|
|
145
142
|
}
|
|
146
143
|
|
|
147
|
-
function
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
},
|
|
144
|
+
async function buildServer(config: ResolvedConfig): Promise<void> {
|
|
145
|
+
const cpOptions: CopyOptions = {
|
|
146
|
+
recursive: true,
|
|
147
|
+
filter: (src) =>
|
|
148
|
+
!src.includes("__tests__") &&
|
|
149
|
+
!src.includes(".test.") &&
|
|
150
|
+
!src.includes(".spec."),
|
|
155
151
|
};
|
|
152
|
+
|
|
153
|
+
await Promise.all([
|
|
154
|
+
// Copy dirs
|
|
155
|
+
...[config.serverDir, join(config.rootDir, "shared")].map((src) =>
|
|
156
|
+
cp(src, config.serverOutDir, cpOptions).catch(() => {
|
|
157
|
+
// Ignore errors
|
|
158
|
+
}),
|
|
159
|
+
),
|
|
160
|
+
// Copy root files
|
|
161
|
+
...["bun.lock", "bun.lockb", "tsconfig.json"].map((file) =>
|
|
162
|
+
cp(join(config.rootDir, file), join(config.outDir, file)).catch(() => {
|
|
163
|
+
// Ignore errors
|
|
164
|
+
}),
|
|
165
|
+
),
|
|
166
|
+
]);
|
|
167
|
+
|
|
168
|
+
const packageJson = await Bun.file(config.packageJsonPath)
|
|
169
|
+
.json()
|
|
170
|
+
.catch(() => ({}));
|
|
171
|
+
await Bun.write(
|
|
172
|
+
join(config.outDir, "package.json"),
|
|
173
|
+
JSON.stringify(
|
|
174
|
+
{
|
|
175
|
+
dependencies: packageJson.dependencies,
|
|
176
|
+
devDependencies: packageJson.devDependencies,
|
|
177
|
+
},
|
|
178
|
+
null,
|
|
179
|
+
2,
|
|
180
|
+
),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
await Bun.write(
|
|
184
|
+
join(config.outDir, "server-entry.ts"),
|
|
185
|
+
`import { resolve } from 'node:path';
|
|
186
|
+
|
|
187
|
+
globalThis.aframe = {
|
|
188
|
+
command: "build",
|
|
189
|
+
rootDir: import.meta.dir,
|
|
190
|
+
publicDir: resolve(import.meta.dir, "public"),
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const { default: server } = await import("./server/main");
|
|
194
|
+
|
|
195
|
+
const port = Number(process.env.PORT) || 3000;
|
|
196
|
+
console.log(\`Server running @ http://localhost:\${port}\`);
|
|
197
|
+
server.listen(port);
|
|
198
|
+
`,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const installProc = Bun.spawn(
|
|
202
|
+
["bun", "i", "--production", "--frozen-lockfile"],
|
|
203
|
+
{
|
|
204
|
+
cwd: config.outDir,
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
const installStatus = await installProc.exited;
|
|
208
|
+
if (installStatus !== 0) {
|
|
209
|
+
throw new Error(`Failed to run "bun i --production" in ${config.outDir}`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
await config.hooks?.afterServerBuild?.(config);
|
|
156
213
|
}
|
|
157
214
|
|
|
158
215
|
function getColor(file: string) {
|
|
159
216
|
if (file.endsWith(".js")) return CYAN;
|
|
217
|
+
if (file.endsWith(".ts")) return CYAN;
|
|
218
|
+
if (file.endsWith(".json")) return YELLOW;
|
|
160
219
|
if (file.endsWith(".html")) return GREEN;
|
|
161
220
|
if (file.endsWith(".css")) return MAGENTA;
|
|
162
221
|
if (file.endsWith(".map")) return DIM;
|
|
@@ -189,3 +248,26 @@ async function gzipFile(config: ResolvedConfig, file: string): Promise<void> {
|
|
|
189
248
|
createWriteStream(`${file}.gz`),
|
|
190
249
|
);
|
|
191
250
|
}
|
|
251
|
+
|
|
252
|
+
async function listDirFiles(
|
|
253
|
+
dir: string,
|
|
254
|
+
filter: (path: string) => boolean,
|
|
255
|
+
): Promise<string[]> {
|
|
256
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
257
|
+
const files: string[] = [];
|
|
258
|
+
|
|
259
|
+
for (const entry of entries) {
|
|
260
|
+
const fullPath = join(entry.parentPath, entry.name);
|
|
261
|
+
|
|
262
|
+
if (!filter(fullPath)) continue;
|
|
263
|
+
|
|
264
|
+
if (entry.isFile()) {
|
|
265
|
+
files.push(fullPath);
|
|
266
|
+
} else if (entry.isDirectory()) {
|
|
267
|
+
const subFiles = await listDirFiles(fullPath, filter);
|
|
268
|
+
files.push(...subFiles);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return files;
|
|
273
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {} from "node:url";
|
|
2
1
|
import { dirname, join } from "node:path";
|
|
3
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
3
|
import type { Browser } from "puppeteer";
|
|
@@ -13,7 +12,7 @@ export type PrerenderedRoute = {
|
|
|
13
12
|
export async function prerenderPages(
|
|
14
13
|
config: ResolvedConfig,
|
|
15
14
|
): Promise<PrerenderedRoute[]> {
|
|
16
|
-
if (config.
|
|
15
|
+
if (config.prerender === false) return [];
|
|
17
16
|
|
|
18
17
|
const puppeteer = await import("puppeteer");
|
|
19
18
|
const {
|
|
@@ -22,10 +21,10 @@ export async function prerenderPages(
|
|
|
22
21
|
waitForSelector,
|
|
23
22
|
waitForSelectorVisible,
|
|
24
23
|
waitForTimeout,
|
|
25
|
-
} = config.
|
|
24
|
+
} = config.prerender ?? {};
|
|
26
25
|
|
|
27
26
|
const server = Bun.spawn({
|
|
28
|
-
cmd: ["bun", join(config.
|
|
27
|
+
cmd: ["bun", join(config.outDir, "server-entry.ts")],
|
|
29
28
|
cwd: config.rootDir,
|
|
30
29
|
stdio: ["inherit", "inherit", "inherit"],
|
|
31
30
|
});
|
package/src/server-entry.ts
DELETED
package/src/virtual-modules.d.ts
DELETED