nukejs 0.0.5 → 0.0.7
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 +96 -8
- package/dist/Link.js +16 -0
- package/dist/Link.js.map +7 -0
- package/dist/build-common.d.ts +57 -80
- package/dist/build-common.js +156 -168
- package/dist/build-common.js.map +2 -2
- package/dist/build-node.d.ts +14 -0
- package/dist/build-node.js +50 -51
- package/dist/build-node.js.map +2 -2
- package/dist/build-vercel.d.ts +18 -0
- package/dist/build-vercel.js +76 -63
- package/dist/build-vercel.js.map +2 -2
- package/dist/builder.d.ts +10 -0
- package/dist/builder.js +31 -62
- package/dist/builder.js.map +3 -3
- package/dist/bundle.js +69 -6
- package/dist/bundle.js.map +2 -2
- package/dist/component-analyzer.d.ts +13 -10
- package/dist/component-analyzer.js +26 -17
- package/dist/component-analyzer.js.map +2 -2
- package/dist/hmr-bundle.js +17 -4
- package/dist/hmr-bundle.js.map +2 -2
- package/dist/html-store.d.ts +7 -0
- package/dist/html-store.js.map +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/renderer.js +2 -7
- package/dist/renderer.js.map +2 -2
- package/dist/router.js +16 -4
- package/dist/router.js.map +2 -2
- package/dist/ssr.js +21 -4
- package/dist/ssr.js.map +2 -2
- package/dist/use-html.js +5 -1
- package/dist/use-html.js.map +2 -2
- package/dist/use-router.js +28 -0
- package/dist/use-router.js.map +7 -0
- package/package.json +1 -1
- package/dist/as-is/Link.tsx +0 -20
- package/dist/as-is/useRouter.ts +0 -33
- /package/dist/{as-is/Link.d.ts → Link.d.ts} +0 -0
- /package/dist/{as-is/useRouter.d.ts → use-router.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://nukejs.com)
|
|
2
|
+
|
|
3
|
+
# NukeJS
|
|
2
4
|
|
|
3
5
|
A **minimal**, opinionated full-stack React framework on Node.js that server-renders everything and hydrates only interactive parts.
|
|
4
6
|
|
|
5
7
|
```
|
|
6
|
-
npm create nuke
|
|
8
|
+
npm create nuke@latest
|
|
7
9
|
```
|
|
8
10
|
|
|
9
11
|
## Table of Contents
|
|
@@ -19,6 +21,7 @@ npm create nuke
|
|
|
19
21
|
- [Static Files](#static-files)
|
|
20
22
|
- [useHtml() — Head Management](#usehtml--head-management)
|
|
21
23
|
- [Configuration](#configuration)
|
|
24
|
+
- [Link Component & Navigation](#link-component--navigation)
|
|
22
25
|
- [Building & Deploying](#building--deploying)
|
|
23
26
|
|
|
24
27
|
## Overview
|
|
@@ -129,8 +132,9 @@ Each `.tsx` file in `app/pages/` maps to a URL route:
|
|
|
129
132
|
| `about.tsx` | `/about` |
|
|
130
133
|
| `blog/index.tsx` | `/blog` |
|
|
131
134
|
| `blog/[slug].tsx` | `/blog/:slug` |
|
|
132
|
-
| `docs/[...path].tsx` | `/docs/*` (catch-all) |
|
|
133
|
-
| `
|
|
135
|
+
| `docs/[...path].tsx` | `/docs/*` (catch-all, required) |
|
|
136
|
+
| `users/[[id]].tsx` | `/users` or `/users/42` (optional single segment) |
|
|
137
|
+
| `files/[[...path]].tsx` | `/files` or `/files/*` (optional catch-all) |
|
|
134
138
|
|
|
135
139
|
### Page component
|
|
136
140
|
|
|
@@ -151,6 +155,28 @@ export default async function BlogPost({ slug }: { slug: string }) {
|
|
|
151
155
|
|
|
152
156
|
Route params are passed as props to the component.
|
|
153
157
|
|
|
158
|
+
### Query string params
|
|
159
|
+
|
|
160
|
+
Query string parameters are automatically merged into the page component's props alongside route params. If a query param shares a name with a route param, the route param takes precedence.
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
// app/pages/search.tsx
|
|
164
|
+
// URL: /search?q=nuke&page=2
|
|
165
|
+
export default function Search({ q, page }: { q: string; page: string }) {
|
|
166
|
+
return <h1>Results for "{q}" — page {page}</h1>;
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
// app/pages/blog/[slug].tsx
|
|
172
|
+
// URL: /blog/hello-world?preview=true
|
|
173
|
+
export default function BlogPost({ slug, preview }: { slug: string; preview?: string }) {
|
|
174
|
+
return <article data-preview={preview}>{slug}</article>;
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
A query param that appears multiple times (e.g. `?tag=a&tag=b`) is passed as a `string[]`.
|
|
179
|
+
|
|
154
180
|
### Catch-all routes
|
|
155
181
|
|
|
156
182
|
```tsx
|
|
@@ -168,9 +194,12 @@ When multiple routes could match a URL, the most specific one wins:
|
|
|
168
194
|
```
|
|
169
195
|
/users/profile → users/profile.tsx (static, wins)
|
|
170
196
|
/users/42 → users/[id].tsx (dynamic)
|
|
197
|
+
/users → users/[[id]].tsx (optional single, matches with no id)
|
|
171
198
|
/users/a/b/c → users/[...rest].tsx (catch-all)
|
|
172
199
|
```
|
|
173
200
|
|
|
201
|
+
Specificity order, highest to lowest: static → `[param]` → `[[param]]` → `[...catchAll]` → `[[...optionalCatchAll]]`.
|
|
202
|
+
|
|
174
203
|
---
|
|
175
204
|
|
|
176
205
|
## Layouts
|
|
@@ -383,13 +412,13 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
|
|
383
412
|
| `nuke build` (Node) | Copied to `dist/static/` and served by the production HTTP server |
|
|
384
413
|
| `nuke build` (Vercel) | Copied to `.vercel/output/static/` — served by Vercel's CDN, no function invocation |
|
|
385
414
|
|
|
386
|
-
On Vercel, public files receive the same zero-latency CDN treatment as `
|
|
415
|
+
On Vercel, public files receive the same zero-latency CDN treatment as `__n.js`.
|
|
387
416
|
|
|
388
417
|
---
|
|
389
418
|
|
|
390
419
|
## useHtml() — Head Management
|
|
391
420
|
|
|
392
|
-
The `useHtml()` hook works in both server components and client components to control the document head
|
|
421
|
+
The `useHtml()` hook works in both server components and client components to control the document `<head>`, `<html>` attributes, `<body>` attributes, and scripts injected at the end of `<body>`.
|
|
393
422
|
|
|
394
423
|
```tsx
|
|
395
424
|
import { useHtml } from 'nukejs';
|
|
@@ -428,6 +457,65 @@ Result: "Home | Site"
|
|
|
428
457
|
|
|
429
458
|
The page title always serves as the base value; layout functions wrap it outward.
|
|
430
459
|
|
|
460
|
+
### Script injection & position
|
|
461
|
+
|
|
462
|
+
The `script` option accepts an array of script tags. Each entry supports the standard attributes (`src`, `type`, `async`, `defer`, `content` for inline scripts, etc.) plus a `position` field:
|
|
463
|
+
|
|
464
|
+
| `position` | Where it's injected |
|
|
465
|
+
|---|---|
|
|
466
|
+
| `'head'` (default) | Inside `<head>`, in the managed `<!--n-head-->` block |
|
|
467
|
+
| `'body'` | End of `<body>`, just before `</body>`, in the `<!--n-body-scripts-->` block |
|
|
468
|
+
|
|
469
|
+
**Use `position: 'body'`** for third-party analytics and tracking scripts (Google Analytics, Hotjar, Intercom, etc.) that should load after page content is in the DOM and must not block rendering.
|
|
470
|
+
|
|
471
|
+
```tsx
|
|
472
|
+
// app/pages/layout.tsx — Google Analytics on every page
|
|
473
|
+
import { useHtml } from 'nukejs';
|
|
474
|
+
|
|
475
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
476
|
+
useHtml({
|
|
477
|
+
script: [
|
|
478
|
+
// Load the gtag library — async so it doesn't block rendering
|
|
479
|
+
{
|
|
480
|
+
src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX',
|
|
481
|
+
async: true,
|
|
482
|
+
position: 'body',
|
|
483
|
+
},
|
|
484
|
+
// Inline initialisation — must follow the loader above
|
|
485
|
+
{
|
|
486
|
+
content: `
|
|
487
|
+
window.dataLayer = window.dataLayer || [];
|
|
488
|
+
function gtag(){dataLayer.push(arguments);}
|
|
489
|
+
gtag('js', new Date());
|
|
490
|
+
gtag('config', 'G-XXXXXXXXXX');
|
|
491
|
+
`,
|
|
492
|
+
position: 'body',
|
|
493
|
+
},
|
|
494
|
+
],
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
return <>{children}</>;
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Use `position: 'head'` (the default)** for scripts that must run before first paint, such as theme detection to avoid flash-of-unstyled-content:
|
|
502
|
+
|
|
503
|
+
```tsx
|
|
504
|
+
useHtml({
|
|
505
|
+
script: [
|
|
506
|
+
{
|
|
507
|
+
content: `
|
|
508
|
+
const theme = localStorage.getItem('theme') ?? 'light';
|
|
509
|
+
document.documentElement.classList.add(theme);
|
|
510
|
+
`,
|
|
511
|
+
// position defaults to 'head' — runs before the page renders
|
|
512
|
+
},
|
|
513
|
+
],
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Both head and body scripts are re-executed on every HMR update and SPA navigation so they always reflect the current page state.
|
|
518
|
+
|
|
431
519
|
---
|
|
432
520
|
|
|
433
521
|
## Configuration
|
|
@@ -506,8 +594,7 @@ dist/
|
|
|
506
594
|
├── api/ # Bundled API route handlers (.mjs)
|
|
507
595
|
├── pages/ # Bundled page handlers (.mjs)
|
|
508
596
|
├── static/
|
|
509
|
-
│ ├──
|
|
510
|
-
│ ├── __n.js # NukeJS client runtime
|
|
597
|
+
│ ├── __n.js # NukeJS client runtime (React + NukeJS bundled together)
|
|
511
598
|
│ ├── __client-component/ # Bundled "use client" component files
|
|
512
599
|
│ └── <app/public files> # Copied from app/public/ at build time
|
|
513
600
|
├── manifest.json # Route dispatch table
|
|
@@ -515,6 +602,7 @@ dist/
|
|
|
515
602
|
```
|
|
516
603
|
|
|
517
604
|
### Vercel
|
|
605
|
+
|
|
518
606
|
Just import the code from GitHub.
|
|
519
607
|
|
|
520
608
|
### Environment variables
|
package/dist/Link.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import useRouter from "./use-router.js";
|
|
4
|
+
const Link = ({ href, children, className }) => {
|
|
5
|
+
const r = useRouter();
|
|
6
|
+
const handleClick = (e) => {
|
|
7
|
+
e.preventDefault();
|
|
8
|
+
r.push(href);
|
|
9
|
+
};
|
|
10
|
+
return /* @__PURE__ */ jsx("a", { href, onClick: handleClick, className, children });
|
|
11
|
+
};
|
|
12
|
+
var Link_default = Link;
|
|
13
|
+
export {
|
|
14
|
+
Link_default as default
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=Link.js.map
|
package/dist/Link.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/Link.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\r\nimport useRouter from \"./use-router\"\r\n\r\nconst Link = ({ href, children, className }: {\r\n href: string;\r\n children: React.ReactNode;\r\n className?: string;\r\n}) => {\r\n const r = useRouter()\r\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\r\n e.preventDefault();\r\n r.push(href);\r\n }\r\n return (\r\n <a href={href} onClick={handleClick} className={className} >\r\n {children}\r\n </a >\r\n );\r\n};\r\n\r\nexport default Link;\r\n"],
|
|
5
|
+
"mappings": ";AAcQ;AAbR,OAAO,eAAe;AAEtB,MAAM,OAAO,CAAC,EAAE,MAAM,UAAU,UAAU,MAIpC;AACF,QAAM,IAAI,UAAU;AACpB,QAAM,cAAc,CAAC,MAA2C;AAC5D,MAAE,eAAe;AACjB,MAAE,KAAK,IAAI;AAAA,EACf;AACA,SACI,oBAAC,OAAE,MAAY,SAAS,aAAa,WAChC,UACL;AAER;AAEA,IAAO,eAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/build-common.d.ts
CHANGED
|
@@ -1,41 +1,59 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* build-common.ts
|
|
2
|
+
* build-common.ts — Shared Build Logic
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Used by both build-node.ts and build-vercel.ts.
|
|
5
5
|
*
|
|
6
6
|
* Exports:
|
|
7
|
-
* —
|
|
8
|
-
*
|
|
9
|
-
* —
|
|
10
|
-
*
|
|
11
|
-
* —
|
|
12
|
-
*
|
|
7
|
+
* — types : AnalyzedRoute, ServerPage, BuiltPage,
|
|
8
|
+
* PageAdapterOptions, PageBundleOptions
|
|
9
|
+
* — utility helpers : walkFiles, analyzeFile, isServerComponent,
|
|
10
|
+
* findPageLayouts, extractDefaultExportName
|
|
11
|
+
* — collection : collectServerPages, collectGlobalClientRegistry,
|
|
12
|
+
* buildPerPageRegistry
|
|
13
|
+
* — template codegen : makeApiAdapterSource, makePageAdapterSource
|
|
14
|
+
* — bundle ops : bundleApiHandler, bundlePageHandler,
|
|
15
|
+
* bundleClientComponents, buildPages,
|
|
16
|
+
* buildCombinedBundle, copyPublicFiles
|
|
13
17
|
*/
|
|
14
18
|
export interface AnalyzedRoute {
|
|
19
|
+
/** Regex string matching the URL path, e.g. '^/users/([^/]+)$' */
|
|
15
20
|
srcRegex: string;
|
|
21
|
+
/** Names of captured groups in srcRegex order */
|
|
16
22
|
paramNames: string[];
|
|
17
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Subset of paramNames that are catch-all ([...slug] or [[...path]]).
|
|
25
|
+
* Their runtime values are string[] not string.
|
|
26
|
+
*/
|
|
27
|
+
catchAllNames: string[];
|
|
28
|
+
/** Function namespace path, e.g. '/api/users' or '/page/about' */
|
|
18
29
|
funcPath: string;
|
|
19
30
|
specificity: number;
|
|
20
31
|
}
|
|
21
32
|
export interface ServerPage extends AnalyzedRoute {
|
|
22
33
|
absPath: string;
|
|
23
34
|
}
|
|
24
|
-
/** A server page together with its fully bundled ESM text, ready to emit. */
|
|
25
35
|
export interface BuiltPage extends ServerPage {
|
|
26
36
|
bundleText: string;
|
|
27
37
|
}
|
|
28
38
|
export declare function walkFiles(dir: string, base?: string): string[];
|
|
29
39
|
/**
|
|
30
40
|
* Parses dynamic-route segments from a relative file path and returns a regex,
|
|
31
|
-
* captured param names, a function path, and a
|
|
41
|
+
* captured param names, catch-all param names, a function path, and a
|
|
42
|
+
* specificity score.
|
|
43
|
+
*
|
|
44
|
+
* Supported patterns per segment:
|
|
45
|
+
* [[...name]] optional catch-all → regex (.*) → string[]
|
|
46
|
+
* [...name] required catch-all → regex (.+) → string[]
|
|
47
|
+
* [[name]] optional single → regex ([^/]*)? → string
|
|
48
|
+
* [name] required single → regex ([^/]+) → string
|
|
49
|
+
* literal static → escaped literal
|
|
32
50
|
*
|
|
33
51
|
* @param relPath Relative path from the dir root (e.g. 'users/[id].tsx').
|
|
34
52
|
* @param prefix Namespace for funcPath ('api' | 'page').
|
|
35
53
|
*/
|
|
36
54
|
export declare function analyzeFile(relPath: string, prefix?: string): AnalyzedRoute;
|
|
37
55
|
/**
|
|
38
|
-
* Returns true when a file does NOT begin with a "use client" directive
|
|
56
|
+
* Returns true when a file does NOT begin with a "use client" directive,
|
|
39
57
|
* i.e. it is a server component.
|
|
40
58
|
*/
|
|
41
59
|
export declare function isServerComponent(filePath: string): boolean;
|
|
@@ -47,26 +65,29 @@ export declare function findPageLayouts(routeFilePath: string, pagesDir: string)
|
|
|
47
65
|
/**
|
|
48
66
|
* Extracts the identifier used as the default export from a component file.
|
|
49
67
|
* Returns null when no default export is found.
|
|
68
|
+
*
|
|
69
|
+
* Handles three formats so that components compiled by esbuild are recognised
|
|
70
|
+
* alongside hand-written source files:
|
|
71
|
+
* 1. Source: `export default function Foo` / `export default Foo`
|
|
72
|
+
* 2. esbuild: `var Foo_default = Foo` (compiled arrow-function component)
|
|
73
|
+
* 3. Re-export: `export { Foo as default }`
|
|
50
74
|
*/
|
|
51
75
|
export declare function extractDefaultExportName(filePath: string): string | null;
|
|
52
76
|
/**
|
|
53
|
-
* Returns all server-component pages inside `pagesDir`, sorted
|
|
54
|
-
*
|
|
77
|
+
* Returns all server-component pages inside `pagesDir`, sorted most-specific
|
|
78
|
+
* first so precise routes shadow catch-alls in routers.
|
|
55
79
|
* layout.tsx files and "use client" files are excluded.
|
|
56
80
|
*/
|
|
57
81
|
export declare function collectServerPages(pagesDir: string): ServerPage[];
|
|
58
82
|
/**
|
|
59
83
|
* Walks every server page and its layout chain to collect all client component
|
|
60
|
-
* IDs reachable anywhere in the app.
|
|
61
|
-
* Map key is the stable content-hash ID produced by component-analyzer.ts.
|
|
84
|
+
* IDs reachable anywhere in the app.
|
|
62
85
|
*/
|
|
63
86
|
export declare function collectGlobalClientRegistry(serverPages: ServerPage[], pagesDir: string): Map<string, string>;
|
|
64
87
|
/**
|
|
65
|
-
* Builds the per-page client component registry (page + its layout chain)
|
|
66
|
-
* returns both the id→path map and the name→id map needed by
|
|
67
|
-
*
|
|
68
|
-
* Extracted here to eliminate the identical loop duplicated across
|
|
69
|
-
* build-node.ts and build-vercel.ts.
|
|
88
|
+
* Builds the per-page client component registry (page + its layout chain)
|
|
89
|
+
* and returns both the id→path map and the name→id map needed by
|
|
90
|
+
* bundlePageHandler.
|
|
70
91
|
*/
|
|
71
92
|
export declare function buildPerPageRegistry(absPath: string, layoutPaths: string[], pagesDir: string): {
|
|
72
93
|
registry: Map<string, string>;
|
|
@@ -79,19 +100,11 @@ export declare function buildPerPageRegistry(absPath: string, layoutPaths: strin
|
|
|
79
100
|
* and collects pre-rendered HTML for each.
|
|
80
101
|
* Pass 2 — bundles every server-component page into a self-contained ESM
|
|
81
102
|
* handler and returns the results as `BuiltPage[]`.
|
|
82
|
-
*
|
|
83
|
-
* Callers (build-node, build-vercel) only need to write the bundled text to
|
|
84
|
-
* their respective output destinations — the format-specific logic stays local.
|
|
85
|
-
*
|
|
86
|
-
* Returns an empty array when there are no server pages.
|
|
87
103
|
*/
|
|
88
104
|
export declare function buildPages(pagesDir: string, staticDir: string): Promise<BuiltPage[]>;
|
|
89
105
|
/**
|
|
90
106
|
* Returns the TypeScript source for a thin HTTP adapter that wraps an API
|
|
91
107
|
* route module and exposes a single `handler(req, res)` default export.
|
|
92
|
-
*
|
|
93
|
-
* @param handlerFilename Basename of the handler file relative to the adapter
|
|
94
|
-
* (e.g. 'users.ts'). Must be in the same directory.
|
|
95
108
|
*/
|
|
96
109
|
export declare function makeApiAdapterSource(handlerFilename: string): string;
|
|
97
110
|
export interface PageAdapterOptions {
|
|
@@ -107,27 +120,24 @@ export interface PageAdapterOptions {
|
|
|
107
120
|
layoutArrayItems: string;
|
|
108
121
|
/** Pre-rendered HTML per client component ID, computed at build time */
|
|
109
122
|
prerenderedHtml: Record<string, string>;
|
|
123
|
+
/** Catch-all param names whose runtime values are string[] not string */
|
|
124
|
+
catchAllNames: string[];
|
|
110
125
|
}
|
|
111
126
|
/**
|
|
112
127
|
* Returns the TypeScript source for a fully self-contained page handler.
|
|
113
128
|
*
|
|
114
129
|
* The adapter:
|
|
115
130
|
* • Inlines the html-store so useHtml() works without external deps.
|
|
116
|
-
* • Contains an async recursive renderer
|
|
117
|
-
* components without react-dom/server.
|
|
131
|
+
* • Contains an async recursive renderer for server + client components.
|
|
118
132
|
* • Client components are identified via the pre-computed CLIENT_COMPONENTS
|
|
119
|
-
* map
|
|
120
|
-
* • Emits the
|
|
121
|
-
* __n_data blob, importmap, and initRuntime bootstrap.
|
|
133
|
+
* map — no fs.readFileSync at runtime.
|
|
134
|
+
* • Emits the full HTML document including the __n_data blob and bootstrap.
|
|
122
135
|
*/
|
|
123
136
|
export declare function makePageAdapterSource(opts: PageAdapterOptions): string;
|
|
124
137
|
/**
|
|
125
138
|
* Bundles an API route handler into a single self-contained ESM string.
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* esbuild (node_modules kept external), then removes the temp file.
|
|
129
|
-
*
|
|
130
|
-
* @returns The bundled ESM text ready to write to disk.
|
|
139
|
+
* node_modules are kept external — they exist at runtime on both Node and
|
|
140
|
+
* Vercel (Vercel bundles them separately via the pages dispatcher).
|
|
131
141
|
*/
|
|
132
142
|
export declare function bundleApiHandler(absPath: string): Promise<string>;
|
|
133
143
|
export interface PageBundleOptions {
|
|
@@ -137,59 +147,26 @@ export interface PageBundleOptions {
|
|
|
137
147
|
allClientIds: string[];
|
|
138
148
|
layoutPaths: string[];
|
|
139
149
|
prerenderedHtml: Record<string, string>;
|
|
150
|
+
catchAllNames: string[];
|
|
140
151
|
}
|
|
141
152
|
/**
|
|
142
153
|
* Bundles a server-component page into a single self-contained ESM string.
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* the component resolve from the correct base directory), bundles it with
|
|
146
|
-
* esbuild (React and all npm deps inlined, only Node built-ins stay external),
|
|
147
|
-
* then removes the temp file.
|
|
148
|
-
*
|
|
149
|
-
* @returns The bundled ESM text ready to write to disk.
|
|
154
|
+
* All npm packages are kept external — the Node production server has
|
|
155
|
+
* node_modules available at runtime.
|
|
150
156
|
*/
|
|
151
157
|
export declare function bundlePageHandler(opts: PageBundleOptions): Promise<string>;
|
|
152
158
|
/**
|
|
153
159
|
* Bundles every client component in `globalRegistry` to
|
|
154
|
-
* `<staticDir>/__client-component/<id>.js
|
|
155
|
-
*
|
|
156
|
-
* Mirrors bundleClientComponent() in bundler.ts:
|
|
157
|
-
* • browser ESM, JSX automatic
|
|
158
|
-
* • react / react-dom/client / react/jsx-runtime kept external so the
|
|
159
|
-
* importmap can resolve them to the already-loaded /__react.js bundle.
|
|
160
|
+
* `<staticDir>/__client-component/<id>.js` and pre-renders each to HTML.
|
|
160
161
|
*/
|
|
161
162
|
export declare function bundleClientComponents(globalRegistry: Map<string, string>, pagesDir: string, staticDir: string): Promise<Map<string, string>>;
|
|
162
163
|
/**
|
|
163
|
-
* Builds
|
|
164
|
-
*
|
|
165
|
-
* Inlines the full React + ReactDOM runtime together with the NukeJS client
|
|
166
|
-
* runtime (bundle.ts) so the browser only needs one file instead of two.
|
|
167
|
-
* The importmap in every page points 'react', 'react-dom/client',
|
|
168
|
-
* 'react/jsx-runtime', and 'nukejs' all to /__n.js, so dynamic imports
|
|
169
|
-
* inside the runtime (e.g. `await import('react')`) hit the module cache
|
|
170
|
-
* and return the same singleton that was already loaded.
|
|
171
|
-
*
|
|
172
|
-
* Dev mode (bundler.ts) keeps separate /__react.js and /__n.js files for
|
|
173
|
-
* easier debugging — this function is production-only.
|
|
164
|
+
* Builds the combined browser bundle (__n.js) that contains the full React
|
|
165
|
+
* runtime + NukeJS client runtime in a single file.
|
|
174
166
|
*/
|
|
175
167
|
export declare function buildCombinedBundle(staticDir: string): Promise<void>;
|
|
176
168
|
/**
|
|
177
|
-
* Recursively copies every file from `
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* Called by both build-vercel.ts (dest = .vercel/output/static/) and
|
|
181
|
-
* build-node.ts (dest = dist/static/) so that:
|
|
182
|
-
*
|
|
183
|
-
* app/public/favicon.ico → <destDir>/favicon.ico
|
|
184
|
-
* app/public/images/logo.png → <destDir>/images/logo.png
|
|
185
|
-
*
|
|
186
|
-
* On Vercel, the Build Output API v3 serves everything in .vercel/output/static/
|
|
187
|
-
* directly — no route entry needed, same as __react.js and __n.js.
|
|
188
|
-
*
|
|
189
|
-
* On Node, the serverEntry template serves files from dist/static/ with the
|
|
190
|
-
* same MIME-type logic as the dev middleware.
|
|
191
|
-
*
|
|
192
|
-
* Skips silently when the public directory does not exist so projects without
|
|
193
|
-
* one don't need any special configuration.
|
|
169
|
+
* Recursively copies every file from `publicDir` into `destDir`, preserving
|
|
170
|
+
* the directory structure. Skips silently when `publicDir` does not exist.
|
|
194
171
|
*/
|
|
195
172
|
export declare function copyPublicFiles(publicDir: string, destDir: string): void;
|