@webtypen/webframez-react 0.0.1 → 0.0.3

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 CHANGED
@@ -1,13 +1,14 @@
1
- # webframez-react
1
+ # @webtypen/webframez-react
2
2
 
3
3
  React Server Components (RSC) extension for `@webtypen/webframez-core`.
4
4
 
5
- `webframez-react` provides:
5
+ `@webtypen/webframez-react` provides:
6
6
  - seamless `webframez-core` integration via `initWebframezReact(Route)`
7
7
  - file-based routing for `pages/**/index.tsx`
8
8
  - layout/error handling with `RouteChildren`
9
9
  - client-side navigation (`Link`, `Redirect`, `useRouter`) and cookies (`useCookie`)
10
10
  - server-rendered initial HTML plus RSC streaming
11
+ - a small CLI for the standard server/client build pipeline
11
12
 
12
13
  ## Requirements
13
14
 
@@ -19,29 +20,269 @@ React Server Components (RSC) extension for `@webtypen/webframez-core`.
19
20
 
20
21
  ```bash
21
22
  npm i @webtypen/webframez-react @webtypen/webframez-core react react-dom react-server-dom-webpack
23
+ npm i -D typescript webpack webpack-cli ts-loader
22
24
  ```
23
25
 
24
26
  ## Quick Start with webframez-core
25
27
 
26
28
  ```ts
27
- // server.ts
28
- import { WebApplication, Route } from "@webtypen/webframez-core";
29
- import { initWebframezReact } from "@webtypen/webframez-react/webframez-core";
29
+ // src/server.ts
30
+ import path from "node:path";
31
+ import { BaseKernelWeb, Route, WebApplication } from "@webtypen/webframez-core";
32
+ import { initWebframezReact } from "@webtypen/webframez-react";
33
+
34
+ class Kernel extends BaseKernelWeb {
35
+ static controller = {};
36
+ static middleware = {};
37
+ }
30
38
 
31
- initWebframezReact(Route);
39
+ const ReactRoute = initWebframezReact(Route);
32
40
 
33
- Route.renderReact("/react", {
34
- distRootDir: `${process.cwd()}/dist`,
41
+ const app = new WebApplication();
42
+ app.boot({
43
+ kernel: Kernel,
44
+ routesFunction: () => {
45
+ ReactRoute.renderReact("/react", {
46
+ distRootDir: path.resolve(process.cwd(), "dist"),
47
+ });
48
+ },
35
49
  });
36
-
37
- WebApplication.boot();
38
50
  ```
39
51
 
40
52
  Notes:
41
53
  - `"/react"` is automatically registered as a catch-all route (`/react/*`).
42
- - `basePath`, `assetsPrefix`, `rscPath`, and `clientScriptUrl` are derived automatically from the mount path.
54
+ - `basePath`, `assetsPrefix`, `rscPath`, and `clientScriptUrl` are derived automatically from the mount path unless you override them.
55
+ - `initWebframezReact(Route)` returns the extended route facade, which gives you reliable editor autocompletion for `renderReact(...)` even in monorepos or symlinked development setups.
56
+ - The package also ships module augmentation for `Route.renderReact(...)`, but using the returned `ReactRoute` variable is the most robust TypeScript setup.
43
57
 
44
- ## Page Structure (File-Based Routing)
58
+ ## `Route.renderReact()`
59
+
60
+ Signature:
61
+
62
+ ```ts
63
+ Route.renderReact(path, options)
64
+ ```
65
+
66
+ Example:
67
+
68
+ ```ts
69
+ Route.renderReact("/app", {
70
+ distRootDir: path.resolve(process.cwd(), "dist"),
71
+ method: "GET",
72
+ routeOptions: {
73
+ middleware: ["auth"],
74
+ },
75
+ });
76
+ ```
77
+
78
+ ### Options
79
+
80
+ `distRootDir`
81
+ - Required.
82
+ - Directory containing the built client assets and generated manifests.
83
+
84
+ `pagesDir`
85
+ - Optional.
86
+ - Directory containing the compiled `pages/**` output.
87
+ - Default: `${distRootDir}/pages`
88
+
89
+ `manifestPath`
90
+ - Optional.
91
+ - Path to the React client manifest.
92
+ - Default: `${distRootDir}/react-client-manifest.json`
93
+
94
+ `assetsPrefix`
95
+ - Optional.
96
+ - Public URL prefix used to serve built client assets.
97
+ - Auto-derived from `path`.
98
+ - Example for `"/react"`: `/react/assets/`
99
+
100
+ `rscPath`
101
+ - Optional.
102
+ - Public URL for the RSC endpoint.
103
+ - Auto-derived from `path`.
104
+ - Example for `"/react"`: `/react/rsc`
105
+
106
+ `clientScriptUrl`
107
+ - Optional.
108
+ - Public URL of the browser client entry bundle.
109
+ - Auto-derived from `path`.
110
+ - Example for `"/react"`: `/react/assets/client.js`
111
+
112
+ `basePath`
113
+ - Optional.
114
+ - Basename mounted in front of all file-router paths.
115
+ - Auto-derived from `path` when `path !== "/"`.
116
+
117
+ `liveReloadPath`
118
+ - Optional.
119
+ - Enables dev live reload on a custom path or disables it explicitly with `false`.
120
+ - Automatically disabled in production mode.
121
+
122
+ `method`
123
+ - Optional.
124
+ - HTTP method or methods used to register the route.
125
+ - Supported values: `"GET" | "POST" | "PUT" | "DELETE"`
126
+ - Default: `"GET"`
127
+
128
+ `routeOptions`
129
+ - Optional.
130
+ - Additional route options forwarded to `webframez-core`.
131
+ - Typical use case: middleware.
132
+
133
+ ## Recommended Project Structure
134
+
135
+ ```txt
136
+ pages/
137
+ layout.tsx
138
+ errors.tsx
139
+ index.tsx
140
+ about/index.tsx
141
+ src/
142
+ server.ts
143
+ client.tsx
144
+ components/
145
+ dist/
146
+ ```
147
+
148
+ ## `tsconfig.server.json`
149
+
150
+ Compared to a standard `@webtypen/webframez-core` project, the server TypeScript config usually needs a few changes:
151
+
152
+ - enable JSX via `"jsx": "react-jsx"`
153
+ - include `pages/**/*.tsx`
154
+ - include `src/components/**/*.tsx`
155
+ - include your server entry (`src/server.ts` or `src/server.tsx`)
156
+ - exclude the browser client entry (`src/client.tsx` by default)
157
+ - add `paths` mappings for the `@webtypen/webframez-react` package and its subpaths
158
+
159
+ When you use the CLI (`webframez-react build:server` / `watch:server`), it generates a temporary `.webframez-react.tsconfig.server.json` that extends your project `tsconfig.server.json`. That means:
160
+
161
+ - your own `tsconfig.server.json` stays the source of truth
162
+ - the CLI only injects the resolved server entry and the standard RSC include/exclude rules
163
+ - you only need to customize the base config when your project structure differs from the defaults
164
+
165
+ A good starting point is the shipped default config:
166
+
167
+ - `@webtypen/webframez-react/defaults/tsconfig.server`
168
+ - `@webtypen/webframez-react/defaults/tsconfig.server.example`
169
+
170
+ Example:
171
+
172
+ ```json
173
+ {
174
+ "compilerOptions": {
175
+ "target": "ES2020",
176
+ "module": "CommonJS",
177
+ "moduleResolution": "Node",
178
+ "baseUrl": ".",
179
+ "paths": {
180
+ "@webtypen/webframez-react": [
181
+ "./node_modules/@webtypen/webframez-react/dist/index.d.ts"
182
+ ],
183
+ "@webtypen/webframez-react/types": [
184
+ "./node_modules/@webtypen/webframez-react/dist/types.d.ts"
185
+ ],
186
+ "@webtypen/webframez-react/router": [
187
+ "./node_modules/@webtypen/webframez-react/dist/router.d.ts"
188
+ ],
189
+ "@webtypen/webframez-react/client": [
190
+ "./node_modules/@webtypen/webframez-react/dist/client.d.ts"
191
+ ],
192
+ "@webtypen/webframez-react/navigation": [
193
+ "./node_modules/@webtypen/webframez-react/dist/navigation.d.ts"
194
+ ],
195
+ "@webtypen/webframez-react/webframez-core": [
196
+ "./node_modules/@webtypen/webframez-react/dist/webframez-core.d.ts"
197
+ ]
198
+ },
199
+ "jsx": "react-jsx",
200
+ "strict": true,
201
+ "esModuleInterop": true,
202
+ "skipLibCheck": true,
203
+ "outDir": "dist",
204
+ "rootDir": "."
205
+ },
206
+ "include": [
207
+ "src/server.ts",
208
+ "src/server.tsx",
209
+ "src/components/**/*.tsx",
210
+ "pages/**/*.tsx",
211
+ "src/types.d.ts"
212
+ ],
213
+ "exclude": [
214
+ "src/client.tsx",
215
+ "dist",
216
+ "node_modules"
217
+ ]
218
+ }
219
+ ```
220
+
221
+ ## `package.json` Scripts
222
+
223
+ Recommended scripts:
224
+
225
+ ```json
226
+ {
227
+ "scripts": {
228
+ "build:server": "webframez-react build:server",
229
+ "build:client": "webframez-react build:client",
230
+ "build": "npm run build:server && npm run build:client",
231
+ "start": "node --conditions react-server start-server.cjs",
232
+ "watch:server": "webframez-react watch:server",
233
+ "watch:client": "webframez-react watch:client",
234
+ "serve:watch": "node --watch --conditions react-server start-server.cjs",
235
+ "watch": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'",
236
+ "dev": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'"
237
+ }
238
+ }
239
+ ```
240
+
241
+ Notes:
242
+ - `build` compiles the server output (`pages`, `server.ts`) and the browser client bundle (`client.tsx` + RSC manifests).
243
+ - `start` runs the built app in React Server mode.
244
+ - `watch` / `dev` keep TypeScript and webpack in watch mode and restart Node automatically when server output changes.
245
+
246
+ ## CLI Config and Custom Entry Paths
247
+
248
+ The CLI first checks project override files and then falls back to the package defaults:
249
+
250
+ - `tsconfig.server.json`
251
+ - `webpack.client.cjs`
252
+ - `webpack.server.cjs`
253
+
254
+ If you do not want to create your own webpack config just to move `client.tsx` or `server.ts`, you can use a small project config file:
255
+
256
+ ```js
257
+ // webframez-react.config.mjs
258
+ export default {
259
+ clientEntryPath: "src/app/client.tsx",
260
+ serverEntryPath: "src/app/server.tsx",
261
+ };
262
+ ```
263
+
264
+ Supported file names:
265
+ - `webframez-react.config.mjs`
266
+ - `webframez-react.config.cjs`
267
+ - `webframez-react.config.js`
268
+ - `webframez-react.config.json`
269
+
270
+ You can also override the entry paths per command:
271
+
272
+ ```bash
273
+ webframez-react build:client --client-entry=src/app/client.tsx
274
+ webframez-react build:server --server-entry=src/app/server.tsx
275
+ webframez-react watch:client --client-entry=src/app/client.tsx
276
+ webframez-react watch:server --server-entry=src/app/server.tsx
277
+ ```
278
+
279
+ Notes:
280
+ - The default client entry is `src/client.tsx`.
281
+ - The default server entry is `src/server.ts`, with automatic fallback to `src/server.tsx` if present.
282
+ - `build:server:webpack` and `watch:server:webpack` also respect `serverEntryPath`.
283
+ - `build:server` and `watch:server` generate a temporary `.webframez-react.tsconfig.server.json` so custom server entry paths also work with the TypeScript compiler.
284
+
285
+ ## File-Based Routing
45
286
 
46
287
  Example:
47
288
 
@@ -60,7 +301,7 @@ pages/
60
301
  "use server";
61
302
 
62
303
  import React from "react";
63
- import { RouteChildren } from "webframez-react/router";
304
+ import { RouteChildren } from "@webtypen/webframez-react/router";
64
305
 
65
306
  export default function Layout() {
66
307
  return (
@@ -81,7 +322,7 @@ Every server page gets `abort()` via `RouteContext`.
81
322
  ```tsx
82
323
  "use server";
83
324
 
84
- import type { PageProps } from "webframez-react/types";
325
+ import type { PageProps } from "@webtypen/webframez-react/types";
85
326
 
86
327
  export default function AccountPage({ params, abort }: PageProps) {
87
328
  if (params.username !== "jane") {
@@ -98,7 +339,7 @@ export default function AccountPage({ params, abort }: PageProps) {
98
339
 
99
340
  Behavior:
100
341
  - default without options: `404` + `"Page not found"`
101
- - rendered through `pages/errors.tsx` (same behavior as unmatched routes)
342
+ - rendered through `pages/errors.tsx`
102
343
  - `pathname` is provided automatically by context
103
344
  - optional `payload` is forwarded to `errors.tsx`
104
345
 
@@ -106,7 +347,7 @@ Behavior:
106
347
 
107
348
  ```tsx
108
349
  // src/client.tsx
109
- import { mountWebframezClient } from "webframez-react/client";
350
+ import { mountWebframezClient } from "@webtypen/webframez-react/client";
110
351
 
111
352
  mountWebframezClient();
112
353
  ```
@@ -126,7 +367,7 @@ mountWebframezClient({
126
367
  "use client";
127
368
 
128
369
  import React from "react";
129
- import { Link, Redirect } from "webframez-react/navigation";
370
+ import { Link, Redirect } from "@webtypen/webframez-react/navigation";
130
371
 
131
372
  export function Nav() {
132
373
  return (
@@ -146,7 +387,7 @@ export function Guard({ loggedIn }: { loggedIn: boolean }) {
146
387
  }
147
388
  ```
148
389
 
149
- Note:
390
+ Notes:
150
391
  - `Link` and `Redirect` automatically use the basename from `Route.renderReact()`.
151
392
  - You can override it per usage via `basename`.
152
393
 
@@ -156,7 +397,7 @@ Note:
156
397
  "use client";
157
398
 
158
399
  import React from "react";
159
- import { useCookie, useRouter } from "webframez-react/client";
400
+ import { useCookie, useRouter } from "@webtypen/webframez-react/client";
160
401
 
161
402
  export default function LoginAction() {
162
403
  const cookie = useCookie();
@@ -177,50 +418,33 @@ export default function LoginAction() {
177
418
 
178
419
  ## Public Entrypoints
179
420
 
180
- - `webframez-react`
181
- - `createNodeRequestHandler`, `createFileRouter`, `createHTMLShell`, `sendRSC`, `createRSCHandler`
182
- - `webframez-react/webframez-core`
421
+ - `@webtypen/webframez-react`
422
+ - `initWebframezReact`
423
+ - `createNodeRequestHandler`
424
+ - `createFileRouter`
425
+ - `createHTMLShell`
426
+ - `sendRSC`
427
+ - `createRSCHandler`
428
+ - `@webtypen/webframez-react/webframez-core`
183
429
  - `initWebframezReact`
184
- - `webframez-react/router`
430
+ - `@webtypen/webframez-react/router`
185
431
  - `RouteChildren`
186
- - `webframez-react/client`
432
+ - `@webtypen/webframez-react/client`
187
433
  - `mountWebframezClient`, `useRouter`, `useCookie`
188
- - `webframez-react/navigation`
434
+ - `@webtypen/webframez-react/navigation`
189
435
  - `Link`, `Redirect`
190
- - `webframez-react/types`
191
- - all public types (`RouteContext`, `PageProps`, `ErrorPageProps`, ...)
192
-
193
- ## package.json Scripts
194
-
195
- Example scripts for a `webframez-react` app:
196
-
197
- ```json
198
- {
199
- "scripts": {
200
- "build:server": "tsc -p tsconfig.server.json",
201
- "build:client": "webpack --config webpack.client.cjs",
202
- "build": "npm run build:server && npm run build:client",
203
- "start": "node --conditions react-server start-server.cjs",
204
- "watch:server": "tsc -p tsconfig.server.json --watch --preserveWatchOutput",
205
- "watch:client": "webpack --config webpack.client.cjs --watch",
206
- "serve:watch": "node --watch --conditions react-server start-server.cjs",
207
- "dev": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'"
208
- }
209
- }
210
- ```
436
+ - `@webtypen/webframez-react/types`
437
+ - `RouteContext`, `PageProps`, `ErrorPageProps`, `AbortRouteOptions`, ...
211
438
 
212
- Notes:
213
- - `build` compiles server output (`pages`, `server.ts`) and client output (`client.tsx` bundle + RSC manifests).
214
- - `start` runs the built app in React Server mode.
215
- - `dev` enables watch mode for TypeScript and webpack and restarts Node automatically on server output changes.
439
+ ## Package Build
216
440
 
217
- ## Build
441
+ Build the package itself:
218
442
 
219
443
  ```bash
220
444
  npm run build
221
445
  ```
222
446
 
223
- Watch mode:
447
+ Watch mode for package development:
224
448
 
225
449
  ```bash
226
450
  npm run build:watch