@webtypen/webframez-react 0.0.2 → 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,14 +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:
6
-
5
+ `@webtypen/webframez-react` provides:
7
6
  - seamless `webframez-core` integration via `initWebframezReact(Route)`
8
7
  - file-based routing for `pages/**/index.tsx`
9
8
  - layout/error handling with `RouteChildren`
10
9
  - client-side navigation (`Link`, `Redirect`, `useRouter`) and cookies (`useCookie`)
11
10
  - server-rendered initial HTML plus RSC streaming
11
+ - a small CLI for the standard server/client build pipeline
12
12
 
13
13
  ## Requirements
14
14
 
@@ -26,111 +26,201 @@ npm i -D typescript webpack webpack-cli ts-loader
26
26
  ## Quick Start with webframez-core
27
27
 
28
28
  ```ts
29
- // server.ts
29
+ // src/server.ts
30
+ import path from "node:path";
30
31
  import { BaseKernelWeb, Route, WebApplication } from "@webtypen/webframez-core";
31
- import { initWebframezReact } from "@webtypen/webframez-react/webframez-core";
32
+ import { initWebframezReact } from "@webtypen/webframez-react";
32
33
 
33
34
  class Kernel extends BaseKernelWeb {
34
35
  static controller = {};
35
36
  static middleware = {};
36
37
  }
37
38
 
38
- initWebframezReact(Route);
39
+ const ReactRoute = initWebframezReact(Route);
39
40
 
40
41
  const app = new WebApplication();
41
42
  app.boot({
42
43
  kernel: Kernel,
43
44
  routesFunction: () => {
44
- Route.renderReact("/react", {
45
- distRootDir: `${process.cwd()}/dist`,
45
+ ReactRoute.renderReact("/react", {
46
+ distRootDir: path.resolve(process.cwd(), "dist"),
46
47
  });
47
48
  },
48
49
  });
49
50
  ```
50
51
 
51
52
  Notes:
52
-
53
53
  - `"/react"` is automatically registered as a catch-all route (`/react/*`).
54
- - `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.
55
57
 
56
- ## Add to an Existing webframez-core Project
58
+ ## `Route.renderReact()`
57
59
 
58
- If you already have a running `@webtypen/webframez-core` app, this is the smallest setup to mount React and return a first JSX page.
60
+ Signature:
59
61
 
60
- 1. Install dependencies:
61
-
62
- ```bash
63
- npm i @webtypen/webframez-react react react-dom react-server-dom-webpack
64
- npm i -D typescript webpack webpack-cli ts-loader
62
+ ```ts
63
+ Route.renderReact(path, options)
65
64
  ```
66
65
 
67
- 2. Extend `Route` and mount React inside your existing `routesFunction`:
66
+ Example:
68
67
 
69
68
  ```ts
70
- // server.ts
71
- import path from "node:path";
72
- import { BaseKernelWeb, Route, WebApplication } from "@webtypen/webframez-core";
73
- import { initWebframezReact } from "@webtypen/webframez-react/webframez-core";
74
-
75
- class Kernel extends BaseKernelWeb {
76
- static controller = {};
77
- static middleware = {};
78
- }
79
-
80
- initWebframezReact(Route);
81
-
82
- const app = new WebApplication();
83
- app.boot({
84
- kernel: Kernel,
85
- port: 3000,
86
- routesFunction: () => {
87
- // Your existing core routes can stay here.
88
- Route.renderReact("/app", {
89
- distRootDir: path.resolve(process.cwd(), "dist"),
90
- });
69
+ Route.renderReact("/app", {
70
+ distRootDir: path.resolve(process.cwd(), "dist"),
71
+ method: "GET",
72
+ routeOptions: {
73
+ middleware: ["auth"],
91
74
  },
92
75
  });
93
76
  ```
94
77
 
95
- 3. Create a minimal file-router page setup:
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
96
134
 
97
- ```tsx
98
- // pages/layout.tsx
99
- "use server";
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
+ ```
100
147
 
101
- import React from "react";
102
- import { RouteChildren } from "@webtypen/webframez-react/router";
148
+ ## `tsconfig.server.json`
103
149
 
104
- export default function Layout() {
105
- return (
106
- <main>
107
- <RouteChildren />
108
- </main>
109
- );
110
- }
111
- ```
150
+ Compared to a standard `@webtypen/webframez-core` project, the server TypeScript config usually needs a few changes:
112
151
 
113
- ```tsx
114
- // pages/index.tsx
115
- "use server";
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
116
158
 
117
- import React from "react";
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:
118
160
 
119
- export default function HomePage() {
120
- return <h1>Hello from webframez-react + JSX</h1>;
121
- }
122
- ```
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
123
164
 
124
- 4. Create the client entry:
165
+ A good starting point is the shipped default config:
125
166
 
126
- ```tsx
127
- // src/client.tsx
128
- import { mountWebframezClient } from "@webtypen/webframez-react/client";
167
+ - `@webtypen/webframez-react/defaults/tsconfig.server`
168
+ - `@webtypen/webframez-react/defaults/tsconfig.server.example`
129
169
 
130
- mountWebframezClient();
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
+ }
131
219
  ```
132
220
 
133
- 5. Add build scripts (with automatic config fallback):
221
+ ## `package.json` Scripts
222
+
223
+ Recommended scripts:
134
224
 
135
225
  ```json
136
226
  {
@@ -138,6 +228,7 @@ mountWebframezClient();
138
228
  "build:server": "webframez-react build:server",
139
229
  "build:client": "webframez-react build:client",
140
230
  "build": "npm run build:server && npm run build:client",
231
+ "start": "node --conditions react-server start-server.cjs",
141
232
  "watch:server": "webframez-react watch:server",
142
233
  "watch:client": "webframez-react watch:client",
143
234
  "serve:watch": "node --watch --conditions react-server start-server.cjs",
@@ -147,9 +238,51 @@ mountWebframezClient();
147
238
  }
148
239
  ```
149
240
 
150
- After build, your first page is available at `http://localhost:3000/app`.
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.
151
284
 
152
- ## Page Structure (File-Based Routing)
285
+ ## File-Based Routing
153
286
 
154
287
  Example:
155
288
 
@@ -205,9 +338,8 @@ export default function AccountPage({ params, abort }: PageProps) {
205
338
  ```
206
339
 
207
340
  Behavior:
208
-
209
341
  - default without options: `404` + `"Page not found"`
210
- - rendered through `pages/errors.tsx` (same behavior as unmatched routes)
342
+ - rendered through `pages/errors.tsx`
211
343
  - `pathname` is provided automatically by context
212
344
  - optional `payload` is forwarded to `errors.tsx`
213
345
 
@@ -255,8 +387,7 @@ export function Guard({ loggedIn }: { loggedIn: boolean }) {
255
387
  }
256
388
  ```
257
389
 
258
- Note:
259
-
390
+ Notes:
260
391
  - `Link` and `Redirect` automatically use the basename from `Route.renderReact()`.
261
392
  - You can override it per usage via `basename`.
262
393
 
@@ -288,7 +419,12 @@ export default function LoginAction() {
288
419
  ## Public Entrypoints
289
420
 
290
421
  - `@webtypen/webframez-react`
291
- - `createNodeRequestHandler`, `createFileRouter`, `createHTMLShell`, `sendRSC`, `createRSCHandler`
422
+ - `initWebframezReact`
423
+ - `createNodeRequestHandler`
424
+ - `createFileRouter`
425
+ - `createHTMLShell`
426
+ - `sendRSC`
427
+ - `createRSCHandler`
292
428
  - `@webtypen/webframez-react/webframez-core`
293
429
  - `initWebframezReact`
294
430
  - `@webtypen/webframez-react/router`
@@ -298,48 +434,17 @@ export default function LoginAction() {
298
434
  - `@webtypen/webframez-react/navigation`
299
435
  - `Link`, `Redirect`
300
436
  - `@webtypen/webframez-react/types`
301
- - all public types (`RouteContext`, `PageProps`, `ErrorPageProps`, ...)
437
+ - `RouteContext`, `PageProps`, `ErrorPageProps`, `AbortRouteOptions`, ...
302
438
 
303
- ## package.json Scripts
304
-
305
- Example scripts for a `webframez-react` app:
306
-
307
- ```json
308
- {
309
- "scripts": {
310
- "build:server": "webframez-react build:server",
311
- "build:client": "webframez-react build:client",
312
- "build": "npm run build:server && npm run build:client",
313
- "start": "node --conditions react-server start-server.cjs",
314
- "watch:server": "webframez-react watch:server",
315
- "watch:client": "webframez-react watch:client",
316
- "serve:watch": "node --watch --conditions react-server start-server.cjs",
317
- "watch": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'",
318
- "dev": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'"
319
- }
320
- }
321
- ```
322
-
323
- Notes:
324
-
325
- - `webframez-react` CLI first checks project overrides and falls back to package defaults:
326
- - `tsconfig.server.json`
327
- - `webpack.client.cjs`
328
- - `webpack.server.cjs`
329
- - `webpack.server.cjs` is optional. Default flow compiles server with `tsc`. Use webpack-server only if you explicitly want a bundled server build:
330
- - `webframez-react build:server:webpack`
331
- - `webframez-react watch:server:webpack`
332
- - `build` compiles server output (`pages`, `server.ts`) and client output (`client.tsx` bundle + RSC manifests).
333
- - `start` runs the built app in React Server mode.
334
- - `watch` and `dev` run the same full watch pipeline and restart Node automatically on server output changes.
439
+ ## Package Build
335
440
 
336
- ## Build
441
+ Build the package itself:
337
442
 
338
443
  ```bash
339
444
  npm run build
340
445
  ```
341
446
 
342
- Watch mode:
447
+ Watch mode for package development:
343
448
 
344
449
  ```bash
345
450
  npm run build:watch
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import fs from "node:fs";
4
+ import fsp from "node:fs/promises";
4
5
  import path from "node:path";
5
6
  import { spawn } from "node:child_process";
6
- import { fileURLToPath } from "node:url";
7
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
8
 
8
9
  const binFilePath = fileURLToPath(import.meta.url);
9
10
  const packageRoot = path.resolve(path.dirname(binFilePath), "..");
@@ -12,6 +13,7 @@ const projectRoot = process.cwd();
12
13
  const command = process.argv[2];
13
14
  const passthroughStart = process.argv[3] === "--" ? 4 : 3;
14
15
  const passthroughArgs = process.argv.slice(passthroughStart);
16
+ const customArgPrefixes = ["--client-entry", "--server-entry"];
15
17
 
16
18
  function printHelp() {
17
19
  console.log(
@@ -34,6 +36,13 @@ function printHelp() {
34
36
  " - tsconfig.server.json",
35
37
  " - webpack.client.cjs",
36
38
  " - webpack.server.cjs",
39
+ "",
40
+ "Optional project config file:",
41
+ " - webframez-react.config.mjs|cjs|js|json",
42
+ "",
43
+ "Optional CLI overrides:",
44
+ " --client-entry=src/client.tsx",
45
+ " --server-entry=src/server.ts",
37
46
  ].join("\n"),
38
47
  );
39
48
  }
@@ -42,6 +51,43 @@ function hasFlag(flag) {
42
51
  return passthroughArgs.includes(flag);
43
52
  }
44
53
 
54
+ function normalizeRelativePath(value) {
55
+ return value.replace(/\\/g, "/");
56
+ }
57
+
58
+ function readCustomArg(name) {
59
+ const withEquals = `${name}=`;
60
+ for (let index = 0; index < passthroughArgs.length; index += 1) {
61
+ const value = passthroughArgs[index];
62
+ if (value === name) {
63
+ return passthroughArgs[index + 1] || null;
64
+ }
65
+ if (value.startsWith(withEquals)) {
66
+ return value.slice(withEquals.length);
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+
72
+ function stripCustomArgs(args) {
73
+ const filtered = [];
74
+ for (let index = 0; index < args.length; index += 1) {
75
+ const value = args[index];
76
+ const matchedPrefix = customArgPrefixes.find(
77
+ (prefix) => value === prefix || value.startsWith(`${prefix}=`),
78
+ );
79
+ if (!matchedPrefix) {
80
+ filtered.push(value);
81
+ continue;
82
+ }
83
+
84
+ if (value === matchedPrefix) {
85
+ index += 1;
86
+ }
87
+ }
88
+ return filtered;
89
+ }
90
+
45
91
  function resolveConfig(localFileName, fallbackFileName) {
46
92
  const localPath = path.resolve(projectRoot, localFileName);
47
93
  if (fs.existsSync(localPath)) {
@@ -69,7 +115,78 @@ function resolveBinary(name) {
69
115
  return name;
70
116
  }
71
117
 
72
- function run(binaryName, args) {
118
+ async function loadProjectConfig() {
119
+ const configFiles = [
120
+ "webframez-react.config.mjs",
121
+ "webframez-react.config.cjs",
122
+ "webframez-react.config.js",
123
+ "webframez-react.config.json",
124
+ ];
125
+
126
+ for (const fileName of configFiles) {
127
+ const filePath = path.resolve(projectRoot, fileName);
128
+ if (!fs.existsSync(filePath)) {
129
+ continue;
130
+ }
131
+
132
+ if (fileName.endsWith(".json")) {
133
+ return JSON.parse(await fsp.readFile(filePath, "utf8"));
134
+ }
135
+
136
+ const imported = await import(pathToFileURL(filePath).href);
137
+ return imported.default ?? imported;
138
+ }
139
+
140
+ return {};
141
+ }
142
+
143
+ function resolveEntryPath(projectConfig, customArgValue, configKey, defaults) {
144
+ const configuredValue = customArgValue || projectConfig?.[configKey];
145
+ if (configuredValue && typeof configuredValue === "string") {
146
+ return path.resolve(projectRoot, configuredValue);
147
+ }
148
+
149
+ for (const defaultPath of defaults) {
150
+ const resolved = path.resolve(projectRoot, defaultPath);
151
+ if (fs.existsSync(resolved)) {
152
+ return resolved;
153
+ }
154
+ }
155
+
156
+ return path.resolve(projectRoot, defaults[0]);
157
+ }
158
+
159
+ async function createServerTsConfig(baseConfig, serverEntryPath, clientEntryPath) {
160
+ const generatedPath = path.resolve(projectRoot, ".webframez-react.tsconfig.server.json");
161
+ const extendsPath =
162
+ baseConfig.source === "project"
163
+ ? `./${normalizeRelativePath(path.basename(baseConfig.path))}`
164
+ : normalizeRelativePath(path.relative(projectRoot, baseConfig.path));
165
+
166
+ const include = [
167
+ normalizeRelativePath(path.relative(projectRoot, serverEntryPath)),
168
+ "src/components/**/*.tsx",
169
+ "pages/**/*.tsx",
170
+ "src/types.d.ts",
171
+ ];
172
+
173
+ const exclude = [
174
+ normalizeRelativePath(path.relative(projectRoot, clientEntryPath)),
175
+ "dist",
176
+ "node_modules",
177
+ ];
178
+
179
+ const generatedConfig = {
180
+ extends: extendsPath,
181
+ include: Array.from(new Set(include)),
182
+ exclude: Array.from(new Set(exclude)),
183
+ };
184
+
185
+ await fsp.writeFile(generatedPath, JSON.stringify(generatedConfig, null, 2));
186
+ return generatedPath;
187
+ }
188
+
189
+ function run(binaryName, args, envAdditions = {}) {
73
190
  const binary = resolveBinary(binaryName);
74
191
 
75
192
  return new Promise((resolve, reject) => {
@@ -77,6 +194,10 @@ function run(binaryName, args) {
77
194
  cwd: projectRoot,
78
195
  stdio: "inherit",
79
196
  shell: false,
197
+ env: {
198
+ ...process.env,
199
+ ...envAdditions,
200
+ },
80
201
  });
81
202
 
82
203
  child.on("error", (error) => {
@@ -95,11 +216,35 @@ async function main() {
95
216
  return;
96
217
  }
97
218
 
219
+ const projectConfig = await loadProjectConfig();
220
+ const customClientEntry = readCustomArg("--client-entry");
221
+ const customServerEntry = readCustomArg("--server-entry");
222
+ const passthroughArgsClean = stripCustomArgs(passthroughArgs);
223
+
224
+ const clientEntryPath = resolveEntryPath(
225
+ projectConfig,
226
+ customClientEntry,
227
+ "clientEntryPath",
228
+ ["src/client.tsx"],
229
+ );
230
+ const serverEntryPath = resolveEntryPath(
231
+ projectConfig,
232
+ customServerEntry,
233
+ "serverEntryPath",
234
+ ["src/server.ts", "src/server.tsx"],
235
+ );
236
+
98
237
  if (command === "build:server" || command === "watch:server") {
99
238
  const config = resolveConfig("tsconfig.server.json", "tsconfig.server.json");
239
+ const generatedConfigPath = await createServerTsConfig(
240
+ config,
241
+ serverEntryPath,
242
+ clientEntryPath,
243
+ );
100
244
  console.log(`[webframez-react] tsc config (${config.source}): ${config.path}`);
245
+ console.log(`[webframez-react] server entry: ${serverEntryPath}`);
101
246
 
102
- const args = ["-p", config.path, ...passthroughArgs];
247
+ const args = ["-p", generatedConfigPath, ...passthroughArgsClean];
103
248
  if (command === "watch:server") {
104
249
  if (!hasFlag("--watch")) {
105
250
  args.push("--watch");
@@ -117,13 +262,16 @@ async function main() {
117
262
  if (command === "build:client" || command === "watch:client") {
118
263
  const config = resolveConfig("webpack.client.cjs", "webpack.client.cjs");
119
264
  console.log(`[webframez-react] webpack config (${config.source}): ${config.path}`);
265
+ console.log(`[webframez-react] client entry: ${clientEntryPath}`);
120
266
 
121
- const args = ["--config", config.path, ...passthroughArgs];
267
+ const args = ["--config", config.path, ...passthroughArgsClean];
122
268
  if (command === "watch:client" && !hasFlag("--watch")) {
123
269
  args.push("--watch");
124
270
  }
125
271
 
126
- const code = await run("webpack", args);
272
+ const code = await run("webpack", args, {
273
+ WEBFRAMEZ_REACT_CLIENT_ENTRY: clientEntryPath,
274
+ });
127
275
  process.exit(code);
128
276
  return;
129
277
  }
@@ -131,13 +279,16 @@ async function main() {
131
279
  if (command === "build:server:webpack" || command === "watch:server:webpack") {
132
280
  const config = resolveConfig("webpack.server.cjs", "webpack.server.cjs");
133
281
  console.log(`[webframez-react] webpack server config (${config.source}): ${config.path}`);
282
+ console.log(`[webframez-react] server entry: ${serverEntryPath}`);
134
283
 
135
- const args = ["--config", config.path, ...passthroughArgs];
284
+ const args = ["--config", config.path, ...passthroughArgsClean];
136
285
  if (command === "watch:server:webpack" && !hasFlag("--watch")) {
137
286
  args.push("--watch");
138
287
  }
139
288
 
140
- const code = await run("webpack", args);
289
+ const code = await run("webpack", args, {
290
+ WEBFRAMEZ_REACT_SERVER_ENTRY: serverEntryPath,
291
+ });
141
292
  process.exit(code);
142
293
  return;
143
294
  }