@orochibraru/svelte-smol 1.4.0 → 1.5.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 +28 -0
- package/index.ts +73 -20
- package/internal.d.ts +1 -0
- package/package.json +1 -1
- package/templates/handler.ts +10 -7
package/README.md
CHANGED
|
@@ -46,12 +46,40 @@ relative to its own path, so it can be run from any working directory:
|
|
|
46
46
|
./build/server
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
### `compile: false`
|
|
50
|
+
|
|
51
|
+
`bun build --compile` bundles every dependency into the binary, and a native
|
|
52
|
+
(`.node`) addon like `sharp` or `better-sqlite3` can't be bundled that way. Set
|
|
53
|
+
`compile: false` to emit a plain bundle instead:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
build/
|
|
57
|
+
├── index.js # the server bundle, run with `bun`
|
|
58
|
+
├── healthcheck # still a compiled binary
|
|
59
|
+
├── client/
|
|
60
|
+
└── prerendered/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bun run ./build/index.js
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Pure-JS dependencies are still bundled into `index.js`. A native addon can't be,
|
|
68
|
+
so its `require` stays in the output and resolves from `node_modules` at runtime
|
|
69
|
+
(looked up from `index.js`'s own location, so the working directory doesn't
|
|
70
|
+
matter). Ship `node_modules` for those — a production install is enough, since
|
|
71
|
+
everything that got bundled needn't be there.
|
|
72
|
+
|
|
73
|
+
Everything else — env vars, the `healthcheck` binary, `serveAssets`,
|
|
74
|
+
instrumentation — works the same.
|
|
75
|
+
|
|
49
76
|
## Options
|
|
50
77
|
|
|
51
78
|
```js
|
|
52
79
|
adapter({
|
|
53
80
|
out: "build", // output directory
|
|
54
81
|
name: "server", // executable filename within `out`
|
|
82
|
+
compile: true, // false → emit build/index.js (run with `bun`) instead of a binary
|
|
55
83
|
target: undefined, // cross-compile target, e.g. "bun-linux-x64"
|
|
56
84
|
bytecode: false, // embed a V8 bytecode cache (faster cold start, bigger binary)
|
|
57
85
|
minify: false, // minify the bundled server code
|
package/index.ts
CHANGED
|
@@ -9,10 +9,23 @@ export interface AdapterOptions {
|
|
|
9
9
|
*/
|
|
10
10
|
out?: string;
|
|
11
11
|
/**
|
|
12
|
-
* Filename of the compiled executable, written into `out`.
|
|
12
|
+
* Filename of the compiled executable, written into `out`. Ignored when
|
|
13
|
+
* {@link AdapterOptions.compile | `compile`} is `false` (the server bundle
|
|
14
|
+
* is always `index.js` then).
|
|
13
15
|
* @default "server"
|
|
14
16
|
*/
|
|
15
17
|
name?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Compile the server to a single standalone executable with
|
|
20
|
+
* `bun build --compile`. Turn this off to emit a plain `build/index.js`
|
|
21
|
+
* bundle instead, run with `bun run build/index.js`. Pure-JS dependencies
|
|
22
|
+
* are still bundled in; a native (`.node`) addon can't be, so it resolves
|
|
23
|
+
* from `node_modules` at runtime — which a `bun` process can do and a
|
|
24
|
+
* compiled binary can't. This is the only way to ship `sharp`, `sqlite3`
|
|
25
|
+
* and the like. The `healthcheck` binary is still compiled either way.
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
compile?: boolean;
|
|
16
29
|
/**
|
|
17
30
|
* Cross-compilation target for `bun build --compile`, e.g.
|
|
18
31
|
* `"bun-linux-x64"`, `"bun-linux-arm64-musl"`, `"bun-darwin-arm64"`,
|
|
@@ -96,6 +109,10 @@ const templates = fileURLToPath(new URL("./templates", import.meta.url));
|
|
|
96
109
|
* Bun runtime (`bun --bun vite build`, or a `bunfig.toml` with `[run] bun =
|
|
97
110
|
* true`); loading the config alone works under Node too.
|
|
98
111
|
*
|
|
112
|
+
* With {@link AdapterOptions.compile | `compile: false`} it emits a plain
|
|
113
|
+
* `build/index.js` bundle instead (run with `bun`), the only way to ship a
|
|
114
|
+
* native (`.node`) addon.
|
|
115
|
+
*
|
|
99
116
|
* Output, all written to {@link AdapterOptions.out | `out`}:
|
|
100
117
|
*
|
|
101
118
|
* ```text
|
|
@@ -140,6 +157,7 @@ export default function adapter(options: AdapterOptions = {}): Adapter {
|
|
|
140
157
|
const {
|
|
141
158
|
out = "build",
|
|
142
159
|
name = "server",
|
|
160
|
+
compile = true,
|
|
143
161
|
target,
|
|
144
162
|
bytecode = false,
|
|
145
163
|
minify = false,
|
|
@@ -209,6 +227,7 @@ export default function adapter(options: AdapterOptions = {}): Adapter {
|
|
|
209
227
|
serveAssets,
|
|
210
228
|
precompress,
|
|
211
229
|
healthcheck: healthcheckConfig,
|
|
230
|
+
compiled: compile,
|
|
212
231
|
}),
|
|
213
232
|
ENV: "./env.ts",
|
|
214
233
|
ENV_PREFIX: JSON.stringify(envPrefix),
|
|
@@ -231,35 +250,69 @@ export default function adapter(options: AdapterOptions = {}): Adapter {
|
|
|
231
250
|
);
|
|
232
251
|
}
|
|
233
252
|
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const result = await Bun.build({
|
|
239
|
-
entrypoints: [entrypoint],
|
|
240
|
-
target: "bun",
|
|
241
|
-
minify,
|
|
242
|
-
bytecode,
|
|
243
|
-
sourcemap: sourcemap ? "linked" : "none",
|
|
244
|
-
compile: {
|
|
245
|
-
outfile: `${out}/${outName}`,
|
|
246
|
-
...(target ? { target } : {}),
|
|
247
|
-
},
|
|
248
|
-
});
|
|
249
|
-
|
|
253
|
+
const check = (
|
|
254
|
+
result: Awaited<ReturnType<typeof Bun.build>>,
|
|
255
|
+
label: string,
|
|
256
|
+
) => {
|
|
250
257
|
if (!result.success) {
|
|
251
258
|
for (const message of result.logs) {
|
|
252
259
|
builder.log.error(String(message));
|
|
253
260
|
}
|
|
254
|
-
throw new Error(`\`bun build
|
|
261
|
+
throw new Error(`\`bun build\` failed for ${label}`);
|
|
255
262
|
}
|
|
263
|
+
};
|
|
256
264
|
|
|
265
|
+
const compileBinary = async (entrypoint: string, outName: string) => {
|
|
266
|
+
builder.log.minor(
|
|
267
|
+
target ? `Compiling ${outName} (${target})` : `Compiling ${outName}`,
|
|
268
|
+
);
|
|
269
|
+
check(
|
|
270
|
+
await Bun.build({
|
|
271
|
+
entrypoints: [entrypoint],
|
|
272
|
+
target: "bun",
|
|
273
|
+
minify,
|
|
274
|
+
bytecode,
|
|
275
|
+
sourcemap: sourcemap ? "linked" : "none",
|
|
276
|
+
compile: {
|
|
277
|
+
outfile: `${out}/${outName}`,
|
|
278
|
+
...(target ? { target } : {}),
|
|
279
|
+
},
|
|
280
|
+
}),
|
|
281
|
+
outName,
|
|
282
|
+
);
|
|
257
283
|
builder.log.success(`Compiled ${out}/${outName}`);
|
|
258
284
|
};
|
|
259
285
|
|
|
260
|
-
|
|
286
|
+
const bundleServer = async (entrypoint: string) => {
|
|
287
|
+
builder.log.minor("Bundling index.js");
|
|
288
|
+
// Same bundle as the compiled binary, just emitted as a file. Every
|
|
289
|
+
// pure-JS dependency is inlined; a native (`.node`) addon can't be,
|
|
290
|
+
// so its `require` stays in the output and resolves from
|
|
291
|
+
// `node_modules` at runtime — which is exactly what a plain `bun`
|
|
292
|
+
// process (unlike a compiled binary) can do. Ship `node_modules`
|
|
293
|
+
// for those; anything fully bundled needn't be installed.
|
|
294
|
+
check(
|
|
295
|
+
await Bun.build({
|
|
296
|
+
entrypoints: [entrypoint],
|
|
297
|
+
target: "bun",
|
|
298
|
+
format: "esm",
|
|
299
|
+
minify,
|
|
300
|
+
sourcemap: sourcemap ? "linked" : "none",
|
|
301
|
+
outdir: out,
|
|
302
|
+
naming: "index.js",
|
|
303
|
+
}),
|
|
304
|
+
"index.js",
|
|
305
|
+
);
|
|
306
|
+
builder.log.success(`Bundled ${out}/index.js`);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
if (compile) {
|
|
310
|
+
await compileBinary(entry, name);
|
|
311
|
+
} else {
|
|
312
|
+
await bundleServer(entry);
|
|
313
|
+
}
|
|
261
314
|
if (healthcheckConfig) {
|
|
262
|
-
await
|
|
315
|
+
await compileBinary(`${tmp}/healthcheck.ts`, "healthcheck");
|
|
263
316
|
}
|
|
264
317
|
},
|
|
265
318
|
};
|
package/internal.d.ts
CHANGED
package/package.json
CHANGED
package/templates/handler.ts
CHANGED
|
@@ -11,7 +11,7 @@ const server = new Server(manifest) as SvelteKitServer & {
|
|
|
11
11
|
websocket?: () => Bun.WebSocketHandler<undefined> | undefined;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
const { serveAssets, precompress, healthcheck } = BUILD_OPTIONS;
|
|
14
|
+
const { serveAssets, precompress, healthcheck, compiled } = BUILD_OPTIONS;
|
|
15
15
|
|
|
16
16
|
const origin = env("ORIGIN", undefined);
|
|
17
17
|
const xff_depth = Number.parseInt(env("XFF_DEPTH", "1"), 10);
|
|
@@ -20,14 +20,17 @@ const protocol_header = env("PROTOCOL_HEADER", "").toLowerCase();
|
|
|
20
20
|
const host_header = env("HOST_HEADER", "").toLowerCase();
|
|
21
21
|
const port_header = env("PORT_HEADER", "").toLowerCase();
|
|
22
22
|
|
|
23
|
-
// Static assets and prerendered pages are deployed next to the
|
|
24
|
-
// <dir>/<
|
|
23
|
+
// Static assets and prerendered pages are deployed next to the server:
|
|
24
|
+
// <dir>/<server>
|
|
25
25
|
// <dir>/client/…
|
|
26
26
|
// <dir>/prerendered/…
|
|
27
|
-
// `ASSETS_DIR` overrides that parent directory (absolute, or relative to
|
|
28
|
-
// binary
|
|
29
|
-
//
|
|
30
|
-
|
|
27
|
+
// `ASSETS_DIR` overrides that parent directory (absolute, or relative to it).
|
|
28
|
+
// In a compiled binary `import.meta.dir` is a virtual path, so the real
|
|
29
|
+
// on-disk location comes from `process.execPath`; in a plain `index.js`
|
|
30
|
+
// bundle `process.execPath` is the `bun` binary, so `import.meta.dir` (the
|
|
31
|
+
// `build/` directory) is the one that's right.
|
|
32
|
+
const self_dir = compiled ? dirname(process.execPath) : import.meta.dir;
|
|
33
|
+
const assets_root = resolve(self_dir, env("ASSETS_DIR", ""));
|
|
31
34
|
const client_dir = `${assets_root}/client${base}`;
|
|
32
35
|
const prerendered_dir = `${assets_root}/prerendered${base}`;
|
|
33
36
|
const immutable_prefix = `${base}/${manifest.appDir}/immutable/`;
|