dinou 4.0.0 → 4.0.2
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/CHANGELOG.md +12 -0
- package/README.md +3 -1
- package/dinou/core/render-html.js +17 -17
- package/dinou/core/server.js +42 -86
- package/dinou/index.mjs +13 -0
- package/dinou/package.json +74 -0
- package/dinou/rollup/rollup.config.js +13 -13
- package/dinou/webpack/webpack.config.js +23 -14
- package/eject.js +53 -6
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [4.0.2]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Export dinou as ESM too.
|
|
13
|
+
|
|
14
|
+
## [4.0.1]
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Starting sequence of the server (generate static pages on background).
|
|
19
|
+
|
|
8
20
|
## [4.0.0]
|
|
9
21
|
|
|
10
22
|
### 🚀 Major Release
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# **Dinou**
|
|
2
2
|
|
|
3
|
+
[](https://dinou.dev)
|
|
4
|
+
|
|
3
5
|
### **Full-Stack React 19 Framework**
|
|
4
6
|
|
|
5
7
|
---
|
|
@@ -1314,7 +1316,7 @@ Netlify is currently incompatible because it does not support passing custom Nod
|
|
|
1314
1316
|
Ensure your platform allows customization of the start command. Your start command should look like:
|
|
1315
1317
|
|
|
1316
1318
|
```bash
|
|
1317
|
-
node --conditions react-server
|
|
1319
|
+
node --conditions react-server ...
|
|
1318
1320
|
```
|
|
1319
1321
|
|
|
1320
1322
|
_(Or use `npm start` if your package.json scripts are configured correctly)._
|
|
@@ -119,10 +119,10 @@ function formatErrorHtmlProduction(error) {
|
|
|
119
119
|
|
|
120
120
|
function writeErrorOutput(error, isProd) {
|
|
121
121
|
process.stdout.write(
|
|
122
|
-
isProd ? formatErrorHtmlProduction(error) : formatErrorHtml(error)
|
|
122
|
+
isProd ? formatErrorHtmlProduction(error) : formatErrorHtml(error),
|
|
123
123
|
);
|
|
124
124
|
process.stderr.write(
|
|
125
|
-
JSON.stringify({ error: error.message, stack: error.stack })
|
|
125
|
+
JSON.stringify({ error: error.message, stack: error.stack }),
|
|
126
126
|
);
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -132,7 +132,7 @@ async function renderToStream(
|
|
|
132
132
|
serializedBox,
|
|
133
133
|
isDynamic,
|
|
134
134
|
hasJsxJson,
|
|
135
|
-
jsxJson
|
|
135
|
+
jsxJson,
|
|
136
136
|
) {
|
|
137
137
|
const context = {
|
|
138
138
|
req: serializedBox.req,
|
|
@@ -146,12 +146,12 @@ async function renderToStream(
|
|
|
146
146
|
isDynamic ||
|
|
147
147
|
!hasJsxJson
|
|
148
148
|
? renderJSXToClientJSX(
|
|
149
|
-
await getJSX(reqPath, query, isNotFound, isDevelopment)
|
|
149
|
+
await getJSX(reqPath, query, isNotFound, isDevelopment),
|
|
150
150
|
)
|
|
151
|
-
: (await getSSGJSX(jsxJson)) ??
|
|
151
|
+
: ((await getSSGJSX(jsxJson)) ??
|
|
152
152
|
renderJSXToClientJSX(
|
|
153
|
-
await getJSX(reqPath, query, isNotFound, isDevelopment)
|
|
154
|
-
);
|
|
153
|
+
await getJSX(reqPath, query, isNotFound, isDevelopment),
|
|
154
|
+
));
|
|
155
155
|
if (isNotFound.value) {
|
|
156
156
|
context.res.status(404);
|
|
157
157
|
}
|
|
@@ -171,7 +171,7 @@ async function renderToStream(
|
|
|
171
171
|
reqPath,
|
|
172
172
|
query,
|
|
173
173
|
error,
|
|
174
|
-
isDevelopment
|
|
174
|
+
isDevelopment,
|
|
175
175
|
);
|
|
176
176
|
|
|
177
177
|
if (!context.res.headersSent) context.res.status(500);
|
|
@@ -200,11 +200,11 @@ async function renderToStream(
|
|
|
200
200
|
].filter(Boolean)
|
|
201
201
|
: [getAssetFromManifest("error.js")],
|
|
202
202
|
bootstrapScriptContent: `window.__DINOU_ERROR_MESSAGE__=${JSON.stringify(
|
|
203
|
-
error.message || "Unknown error"
|
|
203
|
+
error.message || "Unknown error",
|
|
204
204
|
)};window.__DINOU_ERROR_NAME__=${JSON.stringify(error.name)};${
|
|
205
205
|
isDevelopment
|
|
206
206
|
? `window.__DINOU_ERROR_STACK__=${JSON.stringify(
|
|
207
|
-
error.stack || "No stack trace available"
|
|
207
|
+
error.stack || "No stack trace available",
|
|
208
208
|
)};`
|
|
209
209
|
: ""
|
|
210
210
|
}${
|
|
@@ -244,19 +244,19 @@ async function renderToStream(
|
|
|
244
244
|
JSON.stringify({
|
|
245
245
|
error: error.message,
|
|
246
246
|
stack: error.stack,
|
|
247
|
-
})
|
|
247
|
+
}),
|
|
248
248
|
);
|
|
249
249
|
process.exit(1);
|
|
250
250
|
}
|
|
251
251
|
});
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
const reqPath = process.argv[2];
|
|
255
|
-
const query = JSON.parse(process.argv[3]);
|
|
254
|
+
const reqPath = process.argv[2] || "/";
|
|
255
|
+
const query = JSON.parse(process.argv[3] || "{}");
|
|
256
256
|
const serializedBox = JSON.parse(process.argv[4] || "{}");
|
|
257
257
|
const isDynamic = process.argv[5] === "true";
|
|
258
258
|
const hasJsxJson = process.argv[6] === "true";
|
|
259
|
-
const jsxJson = JSON.parse(process.argv[7]);
|
|
259
|
+
const jsxJson = JSON.parse(process.argv[7] || "{}");
|
|
260
260
|
|
|
261
261
|
process.on("uncaughtException", (error) => {
|
|
262
262
|
process.stdout.write(formatErrorHtml(error));
|
|
@@ -264,7 +264,7 @@ process.on("uncaughtException", (error) => {
|
|
|
264
264
|
JSON.stringify({
|
|
265
265
|
error: error.message,
|
|
266
266
|
stack: error.stack,
|
|
267
|
-
})
|
|
267
|
+
}),
|
|
268
268
|
);
|
|
269
269
|
process.exit(1);
|
|
270
270
|
});
|
|
@@ -276,7 +276,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
276
276
|
JSON.stringify({
|
|
277
277
|
error: error.message,
|
|
278
278
|
stack: error.stack,
|
|
279
|
-
})
|
|
279
|
+
}),
|
|
280
280
|
);
|
|
281
281
|
process.exit(1);
|
|
282
282
|
});
|
|
@@ -287,7 +287,7 @@ renderToStream(
|
|
|
287
287
|
serializedBox,
|
|
288
288
|
isDynamic,
|
|
289
289
|
hasJsxJson,
|
|
290
|
-
jsxJson
|
|
290
|
+
jsxJson,
|
|
291
291
|
).catch((err) => {
|
|
292
292
|
console.error("❌ Fatal error starting render stream:", err);
|
|
293
293
|
process.exit(1);
|
package/dinou/core/server.js
CHANGED
|
@@ -436,42 +436,14 @@ function getContextForServerFunctionEndpoint(req, res) {
|
|
|
436
436
|
|
|
437
437
|
app.use(express.static(path.resolve(process.cwd(), outputFolder)));
|
|
438
438
|
|
|
439
|
-
// app.use((req, res, next) => {
|
|
440
|
-
// // Make sure NOT to return 200 if what is requested is a .js that doesn't exist
|
|
441
|
-
// if (
|
|
442
|
-
// req.path.endsWith(".js") ||
|
|
443
|
-
// req.path.endsWith(".css") ||
|
|
444
|
-
// req.path.endsWith(".png") ||
|
|
445
|
-
// req.path.endsWith(".jpg") ||
|
|
446
|
-
// req.path.endsWith(".svg") ||
|
|
447
|
-
// req.path.endsWith(".webp") ||
|
|
448
|
-
// req.path.endsWith(".ico") ||
|
|
449
|
-
// req.path.endsWith(".json")
|
|
450
|
-
// ) {
|
|
451
|
-
// return res.status(404).send("Not found");
|
|
452
|
-
// }
|
|
453
|
-
// next();
|
|
454
|
-
// // ... Dinou rendering ...
|
|
455
|
-
// });
|
|
456
|
-
|
|
457
439
|
let isReady = isDevelopment; // In dev we are always ready (or almost)
|
|
458
440
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
// If we are in PROD and generateStatic hasn't finished yet...
|
|
466
|
-
if (!isReady) {
|
|
467
|
-
// Optional: Allow health-checks or assets if you want
|
|
468
|
-
// if (req.path.endsWith('.js')) return next();
|
|
469
|
-
|
|
470
|
-
// Return 503 (Service Unavailable)
|
|
471
|
-
// Playwright understands that 503 means "Keep waiting"
|
|
472
|
-
return res.status(503).send("Server warming up (generating static)...");
|
|
473
|
-
}
|
|
474
|
-
next();
|
|
441
|
+
app.get("/__DINOU_STATUS_PLAYWRIGHT__", (req, res) => {
|
|
442
|
+
res.json({
|
|
443
|
+
status: "ok",
|
|
444
|
+
isReady,
|
|
445
|
+
mode: isDevelopment ? "development" : "production",
|
|
446
|
+
});
|
|
475
447
|
});
|
|
476
448
|
|
|
477
449
|
app.get("/.well-known/appspecific/com.chrome.devtools.json", (req, res) => {
|
|
@@ -759,8 +731,8 @@ app.get(/^\/.*\/?$/, (req, res) => {
|
|
|
759
731
|
if (
|
|
760
732
|
!isDevelopment &&
|
|
761
733
|
res.statusCode === 200 && // Only if success
|
|
762
|
-
req.method === "GET" // Only GET requests
|
|
763
|
-
|
|
734
|
+
req.method === "GET" && // Only GET requests
|
|
735
|
+
isReady
|
|
764
736
|
) {
|
|
765
737
|
generatingISG(reqPath, dynamicState);
|
|
766
738
|
}
|
|
@@ -983,70 +955,54 @@ const port = process.env.PORT || 3000;
|
|
|
983
955
|
|
|
984
956
|
const http = require("http");
|
|
985
957
|
|
|
986
|
-
//
|
|
958
|
+
// ============================================================
|
|
959
|
+
// STARTUP SEQUENCE
|
|
960
|
+
// ============================================================
|
|
987
961
|
(async () => {
|
|
988
962
|
try {
|
|
989
|
-
// ============================================================
|
|
990
|
-
// PHASE 1: STATIC GENERATION (Build Time)
|
|
991
|
-
// ============================================================
|
|
992
|
-
// We do this BEFORE creating the server. This way, if generateStatic
|
|
993
|
-
// performs aggressive memory cleanups, it doesn't kill the HTTP server.
|
|
994
|
-
if (!isDevelopment) {
|
|
995
|
-
console.log("🏗️ [Startup] Starting static generation (SSG/ISR)...");
|
|
996
|
-
try {
|
|
997
|
-
await generateStatic();
|
|
998
|
-
console.log("✅ [Startup] Static generation finished successfully.");
|
|
999
|
-
} catch (buildError) {
|
|
1000
|
-
console.error("❌ [Startup] Static generation failed:", buildError);
|
|
1001
|
-
// Depending on your policy, you could exit (process.exit(1)) or continue
|
|
1002
|
-
// If you decide to continue, the server will start but files might be missing.
|
|
1003
|
-
process.exit(1);
|
|
1004
|
-
}
|
|
1005
|
-
} else {
|
|
1006
|
-
console.log(
|
|
1007
|
-
"⚙️ [Startup] Running in Development Mode (Dynamic Rendering)"
|
|
1008
|
-
);
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
// ============================================================
|
|
1012
|
-
// PHASE 2: SERVER CREATION
|
|
1013
|
-
// ============================================================
|
|
1014
963
|
console.log("👉 [Startup] Initializing HTTP Server...");
|
|
1015
|
-
|
|
1016
|
-
// We pass 'app' to createServer. This decouples Express from the network.
|
|
1017
964
|
const server = http.createServer(app);
|
|
1018
965
|
|
|
1019
|
-
//
|
|
1020
|
-
// PHASE 3: ERROR HANDLING (Anti-Zombies)
|
|
1021
|
-
// ============================================================
|
|
1022
|
-
// This captures errors like EADDRINUSE before they silently crash the process
|
|
966
|
+
// 2. ERROR HANDLING (Anti-Zombies)
|
|
1023
967
|
server.on("error", (error) => {
|
|
1024
968
|
if (error.code === "EADDRINUSE") {
|
|
1025
969
|
console.error(`\n❌ FATAL ERROR: Port ${port} is already in use!`);
|
|
1026
|
-
console.error(
|
|
1027
|
-
` Cause: A previous instance, a zombie test runner, or another app is holding the port.`
|
|
1028
|
-
);
|
|
1029
|
-
console.error(
|
|
1030
|
-
` Action: Run 'netstat -ano | findstr :${port}' (Win) or 'lsof -i :${port}' to find the PID and kill it.\n`
|
|
1031
|
-
);
|
|
1032
970
|
} else {
|
|
1033
971
|
console.error("❌ [Server Error]:", error);
|
|
1034
972
|
}
|
|
1035
|
-
process.exit(1);
|
|
973
|
+
process.exit(1);
|
|
1036
974
|
});
|
|
1037
975
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
);
|
|
976
|
+
await new Promise((resolve) => {
|
|
977
|
+
server.listen(port, () => {
|
|
978
|
+
console.log(
|
|
979
|
+
`\n🚀 Dinou Server is ready and listening on http://localhost:${port}`
|
|
980
|
+
);
|
|
981
|
+
console.log(
|
|
982
|
+
` Environment: ${isDevelopment ? "Development" : "Production"}`
|
|
983
|
+
);
|
|
984
|
+
resolve();
|
|
985
|
+
});
|
|
1049
986
|
});
|
|
987
|
+
|
|
988
|
+
if (!isDevelopment) {
|
|
989
|
+
console.log("🏗️ [Background] Starting static generation (SSG)...");
|
|
990
|
+
|
|
991
|
+
generateStatic()
|
|
992
|
+
.then(() => {
|
|
993
|
+
console.log("✅ [Background] Static generation finished.");
|
|
994
|
+
isReady = true;
|
|
995
|
+
})
|
|
996
|
+
.catch((err) => {
|
|
997
|
+
console.error(
|
|
998
|
+
"❌ [Background] Static generation failed (App continues in Dynamic Mode):",
|
|
999
|
+
err
|
|
1000
|
+
);
|
|
1001
|
+
isReady = true;
|
|
1002
|
+
});
|
|
1003
|
+
} else {
|
|
1004
|
+
console.log("⚙️ [Startup] Running in Development Mode");
|
|
1005
|
+
}
|
|
1050
1006
|
} catch (error) {
|
|
1051
1007
|
console.error("💥 [Fatal Startup Error]:", error);
|
|
1052
1008
|
process.exit(1);
|
package/dinou/index.mjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// dinou/index.mjs
|
|
2
|
+
import dinou from "./index.js";
|
|
3
|
+
|
|
4
|
+
export const getContext = dinou.getContext;
|
|
5
|
+
export const usePathname = dinou.usePathname;
|
|
6
|
+
export const useSearchParams = dinou.useSearchParams;
|
|
7
|
+
export const useRouter = dinou.useRouter;
|
|
8
|
+
export const useNavigationLoading = dinou.useNavigationLoading;
|
|
9
|
+
export const redirect = dinou.redirect;
|
|
10
|
+
export const ClientRedirect = dinou.ClientRedirect;
|
|
11
|
+
export const Link = dinou.Link;
|
|
12
|
+
|
|
13
|
+
export default dinou;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dinou",
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"private": true,
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./index.mjs",
|
|
9
|
+
"require": "./index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@babel/core": "^7.27.4",
|
|
18
|
+
"@babel/parser": "^7.28.3",
|
|
19
|
+
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
|
20
|
+
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
|
21
|
+
"@babel/preset-react": "^7.27.1",
|
|
22
|
+
"@babel/preset-typescript": "^7.27.1",
|
|
23
|
+
"@babel/register": "^7.27.1",
|
|
24
|
+
"@babel/traverse": "^7.28.3",
|
|
25
|
+
"@esbuild-plugins/tsconfig-paths": "^0.1.2",
|
|
26
|
+
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
|
27
|
+
"@roggc/react-server-dom-esm": "^0.0.0-b061b597-20251212",
|
|
28
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
29
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
30
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
31
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
32
|
+
"@rollup/plugin-replace": "^6.0.2",
|
|
33
|
+
"@tailwindcss/postcss": "^4.1.10",
|
|
34
|
+
"autoprefixer": "^10.4.21",
|
|
35
|
+
"babel-loader": "^10.0.0",
|
|
36
|
+
"chokidar": "^4.0.3",
|
|
37
|
+
"commander": "^14.0.0",
|
|
38
|
+
"concurrently": "^9.2.0",
|
|
39
|
+
"cookie-parser": "^1.4.7",
|
|
40
|
+
"copy-webpack-plugin": "^13.0.1",
|
|
41
|
+
"cross-env": "^7.0.3",
|
|
42
|
+
"css-loader": "^7.1.2",
|
|
43
|
+
"css-modules-require-hook": "^4.2.3",
|
|
44
|
+
"dotenv": "^16.5.0",
|
|
45
|
+
"esbuild": "^0.27.0",
|
|
46
|
+
"esbuild-copy-static-files": "^0.1.0",
|
|
47
|
+
"express": "^5.1.0",
|
|
48
|
+
"generic-names": "^4.0.0",
|
|
49
|
+
"loader-utils": "^3.3.1",
|
|
50
|
+
"mini-css-extract-plugin": "^2.9.4",
|
|
51
|
+
"postcss": "^8.5.5",
|
|
52
|
+
"postcss-import": "^16.1.1",
|
|
53
|
+
"postcss-loader": "^8.2.0",
|
|
54
|
+
"postcss-modules": "^6.0.1",
|
|
55
|
+
"react-refresh": "^0.17.0",
|
|
56
|
+
"react-server-dom-webpack": "^19.2.3",
|
|
57
|
+
"rollup": "^4.46.2",
|
|
58
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
59
|
+
"rollup-plugin-delete": "^3.0.1",
|
|
60
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
61
|
+
"rollup-plugin-tsconfig-paths": "^1.5.2",
|
|
62
|
+
"tailwindcss": "^4.1.10",
|
|
63
|
+
"tsconfig-paths": "^4.2.0",
|
|
64
|
+
"tsconfig-paths-webpack-plugin": "^4.2.0",
|
|
65
|
+
"webpack": "^5.103.0",
|
|
66
|
+
"webpack-cli": "^6.0.1",
|
|
67
|
+
"webpack-dev-server": "^5.2.2",
|
|
68
|
+
"ws": "^8.18.3"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"react": ">=19.2.3",
|
|
72
|
+
"react-dom": ">=19.2.3"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -20,7 +20,7 @@ const manifestGeneratorPlugin = require("./rollup-plugins/manifest-generator-plu
|
|
|
20
20
|
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
21
21
|
const outputDirectory = isDevelopment ? "public" : "dist3";
|
|
22
22
|
|
|
23
|
-
const localDinouPath = path.resolve(process.cwd(), "dinou
|
|
23
|
+
const localDinouPath = path.resolve(process.cwd(), "dinou");
|
|
24
24
|
// const localNavigationPath = path.resolve(
|
|
25
25
|
// process.cwd(),
|
|
26
26
|
// "dinou/core/navigation.js"
|
|
@@ -30,7 +30,7 @@ const isEjected = fs.existsSync(localDinouPath);
|
|
|
30
30
|
console.log(
|
|
31
31
|
isEjected
|
|
32
32
|
? "🚀 [Dinou] Ejected Mode detected (Using local code)"
|
|
33
|
-
: "📦 [Dinou] Library Mode detected (Using node_modules)"
|
|
33
|
+
: "📦 [Dinou] Library Mode detected (Using node_modules)",
|
|
34
34
|
);
|
|
35
35
|
|
|
36
36
|
// ----------------------------------------------------------------------
|
|
@@ -60,21 +60,21 @@ module.exports = async function () {
|
|
|
60
60
|
? {
|
|
61
61
|
runtime: path.resolve(
|
|
62
62
|
__dirname,
|
|
63
|
-
"react-refresh/react-refresh-runtime.js"
|
|
63
|
+
"react-refresh/react-refresh-runtime.js",
|
|
64
64
|
),
|
|
65
65
|
refresh: path.resolve(
|
|
66
66
|
__dirname,
|
|
67
|
-
"react-refresh/react-refresh-entry.js"
|
|
67
|
+
"react-refresh/react-refresh-entry.js",
|
|
68
68
|
),
|
|
69
69
|
main: path.resolve(__dirname, "../core/client.jsx"),
|
|
70
70
|
error: path.resolve(__dirname, "../core/client-error.jsx"),
|
|
71
71
|
serverFunctionProxy: path.resolve(
|
|
72
72
|
__dirname,
|
|
73
|
-
"../core/server-function-proxy.js"
|
|
73
|
+
"../core/server-function-proxy.js",
|
|
74
74
|
),
|
|
75
75
|
dinouClientRedirect: path.resolve(
|
|
76
76
|
__dirname,
|
|
77
|
-
"../core/client-redirect.jsx"
|
|
77
|
+
"../core/client-redirect.jsx",
|
|
78
78
|
),
|
|
79
79
|
}
|
|
80
80
|
: {
|
|
@@ -82,11 +82,11 @@ module.exports = async function () {
|
|
|
82
82
|
error: path.resolve(__dirname, "../core/client-error.jsx"),
|
|
83
83
|
serverFunctionProxy: path.resolve(
|
|
84
84
|
__dirname,
|
|
85
|
-
"../core/server-function-proxy.js"
|
|
85
|
+
"../core/server-function-proxy.js",
|
|
86
86
|
),
|
|
87
87
|
dinouClientRedirect: path.resolve(
|
|
88
88
|
__dirname,
|
|
89
|
-
"../core/client-redirect.jsx"
|
|
89
|
+
"../core/client-redirect.jsx",
|
|
90
90
|
),
|
|
91
91
|
},
|
|
92
92
|
output: {
|
|
@@ -110,7 +110,7 @@ module.exports = async function () {
|
|
|
110
110
|
// "dinou",
|
|
111
111
|
],
|
|
112
112
|
plugins: [
|
|
113
|
-
isEjected && localDinouAlias(),
|
|
113
|
+
// isEjected && localDinouAlias(),
|
|
114
114
|
del({
|
|
115
115
|
targets: [
|
|
116
116
|
`${outputDirectory}/*`,
|
|
@@ -124,7 +124,7 @@ module.exports = async function () {
|
|
|
124
124
|
replace({
|
|
125
125
|
preventAssignment: true,
|
|
126
126
|
"process.env.NODE_ENV": JSON.stringify(
|
|
127
|
-
isDevelopment ? "development" : "production"
|
|
127
|
+
isDevelopment ? "development" : "production",
|
|
128
128
|
),
|
|
129
129
|
}),
|
|
130
130
|
json(),
|
|
@@ -176,7 +176,7 @@ module.exports = async function () {
|
|
|
176
176
|
reactClientManifest({
|
|
177
177
|
manifestPath: path.join(
|
|
178
178
|
"react_client_manifest",
|
|
179
|
-
"react-client-manifest.json"
|
|
179
|
+
"react-client-manifest.json",
|
|
180
180
|
),
|
|
181
181
|
}),
|
|
182
182
|
isDevelopment && reactRefreshWrapModules(),
|
|
@@ -199,10 +199,10 @@ module.exports = async function () {
|
|
|
199
199
|
}
|
|
200
200
|
if (
|
|
201
201
|
warning.message.includes(
|
|
202
|
-
'Module level directives cause errors when bundled, "use client"'
|
|
202
|
+
'Module level directives cause errors when bundled, "use client"',
|
|
203
203
|
) ||
|
|
204
204
|
warning.message.includes(
|
|
205
|
-
'Module level directives cause errors when bundled, "use server"'
|
|
205
|
+
'Module level directives cause errors when bundled, "use server"',
|
|
206
206
|
)
|
|
207
207
|
) {
|
|
208
208
|
return;
|
|
@@ -28,33 +28,38 @@ function getConfigFileIfExists() {
|
|
|
28
28
|
|
|
29
29
|
const configFile = getConfigFileIfExists();
|
|
30
30
|
|
|
31
|
-
const localDinouPath = path.resolve(process.cwd(), "dinou
|
|
31
|
+
const localDinouPath = path.resolve(process.cwd(), "dinou");
|
|
32
32
|
const isEjected = fs.existsSync(localDinouPath);
|
|
33
33
|
|
|
34
34
|
console.log(
|
|
35
35
|
isEjected
|
|
36
36
|
? "🚀 [Dinou] Ejected Mode detected (Webpack: Using local code)"
|
|
37
|
-
: "📦 [Dinou] Library Mode detected (Webpack: Using node_modules)"
|
|
37
|
+
: "📦 [Dinou] Library Mode detected (Webpack: Using node_modules)",
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
module.exports = async () => {
|
|
41
41
|
const [cssEntries] = await getCSSEntries();
|
|
42
42
|
return {
|
|
43
|
+
performance: {
|
|
44
|
+
hints: isDevelopment ? false : "warning",
|
|
45
|
+
maxEntrypointSize: 512000,
|
|
46
|
+
maxAssetSize: 512000,
|
|
47
|
+
},
|
|
43
48
|
mode: isDevelopment ? "development" : "production",
|
|
44
49
|
entry: {
|
|
45
50
|
main: [path.resolve(__dirname, "../core/client-webpack.jsx")].filter(
|
|
46
|
-
Boolean
|
|
51
|
+
Boolean,
|
|
47
52
|
),
|
|
48
53
|
error: [
|
|
49
54
|
path.resolve(__dirname, "../core/client-error-webpack.jsx"),
|
|
50
55
|
].filter(Boolean),
|
|
51
56
|
serverFunctionProxy: path.resolve(
|
|
52
57
|
__dirname,
|
|
53
|
-
"../core/server-function-proxy-webpack.js"
|
|
58
|
+
"../core/server-function-proxy-webpack.js",
|
|
54
59
|
),
|
|
55
60
|
dinouClientRedirect: path.resolve(
|
|
56
61
|
__dirname,
|
|
57
|
-
"../core/client-redirect.jsx"
|
|
62
|
+
"../core/client-redirect.jsx",
|
|
58
63
|
),
|
|
59
64
|
dinouLink: path.resolve(__dirname, "../core/link.jsx"),
|
|
60
65
|
...[...cssEntries].reduce(
|
|
@@ -62,7 +67,7 @@ module.exports = async () => {
|
|
|
62
67
|
...acc,
|
|
63
68
|
[cssEntry.outfileName]: cssEntry.absPath,
|
|
64
69
|
}),
|
|
65
|
-
{}
|
|
70
|
+
{},
|
|
66
71
|
),
|
|
67
72
|
},
|
|
68
73
|
experiments: {
|
|
@@ -95,12 +100,12 @@ module.exports = async () => {
|
|
|
95
100
|
|
|
96
101
|
{
|
|
97
102
|
test: /\.(js|jsx|ts|tsx)$/,
|
|
98
|
-
include: [
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
].filter(Boolean),
|
|
103
|
+
// include: [
|
|
104
|
+
// path.resolve(process.cwd(), "src"),
|
|
105
|
+
// path.resolve(__dirname, "../core"),
|
|
106
|
+
// path.resolve(process.cwd(), "node_modules/dinou"),
|
|
107
|
+
// isEjected && path.resolve(process.cwd(), "dinou"),
|
|
108
|
+
// ].filter(Boolean),
|
|
104
109
|
use: {
|
|
105
110
|
loader: "babel-loader",
|
|
106
111
|
options: {
|
|
@@ -127,7 +132,7 @@ module.exports = async () => {
|
|
|
127
132
|
{
|
|
128
133
|
loader: path.resolve(
|
|
129
134
|
__dirname,
|
|
130
|
-
"./loaders/server-functions-loader.js"
|
|
135
|
+
"./loaders/server-functions-loader.js",
|
|
131
136
|
),
|
|
132
137
|
},
|
|
133
138
|
],
|
|
@@ -182,7 +187,7 @@ module.exports = async () => {
|
|
|
182
187
|
|
|
183
188
|
const base = path.basename(
|
|
184
189
|
resourcePath,
|
|
185
|
-
path.extname(resourcePath)
|
|
190
|
+
path.extname(resourcePath),
|
|
186
191
|
);
|
|
187
192
|
const scoped = createScopedName(base, resourcePath);
|
|
188
193
|
|
|
@@ -218,6 +223,10 @@ module.exports = async () => {
|
|
|
218
223
|
resolve: {
|
|
219
224
|
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
|
220
225
|
modules: ["src", "node_modules"],
|
|
226
|
+
extensionAlias: {
|
|
227
|
+
".js": [".js", ".ts", ".tsx"],
|
|
228
|
+
".jsx": [".jsx", ".tsx"],
|
|
229
|
+
},
|
|
221
230
|
// 🎯 ADD THIS:
|
|
222
231
|
alias: {
|
|
223
232
|
...(isEjected ? { dinou: localDinouPath } : {}),
|
package/eject.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
+
const { execSync } = require("child_process");
|
|
3
4
|
|
|
4
5
|
const dinouPath = path.resolve(__dirname, "dinou");
|
|
5
6
|
const projectRoot = process.cwd();
|
|
6
7
|
|
|
8
|
+
console.log("🚀 Starting Dinou ejecting process...");
|
|
9
|
+
|
|
7
10
|
fs.cpSync(dinouPath, path.join(projectRoot, "dinou"), {
|
|
8
11
|
recursive: true,
|
|
9
12
|
});
|
|
13
|
+
console.log("✅ Files copyed to ./dinou");
|
|
14
|
+
|
|
15
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
16
|
+
const pkg = require(pkgPath);
|
|
10
17
|
|
|
11
|
-
const pkg = require(path.join(projectRoot, "package.json"));
|
|
12
18
|
pkg.scripts["dev:express"] =
|
|
13
19
|
"node --conditions react-server --import ./dinou/core/register-loader.mjs ./dinou/core/server.js";
|
|
14
20
|
pkg.scripts["dev_rollup"] = "rollup -c ./dinou/rollup/rollup.config.js -w";
|
|
@@ -39,9 +45,50 @@ pkg.scripts["start:webpack"] =
|
|
|
39
45
|
"cross-env NODE_ENV=production DINOU_BUILD_TOOL=webpack node --conditions react-server --import ./dinou/core/register-loader.mjs ./dinou/core/server.js";
|
|
40
46
|
pkg.scripts.start = "npm run start:esbuild";
|
|
41
47
|
delete pkg.scripts.eject;
|
|
42
|
-
fs.writeFileSync(
|
|
43
|
-
path.join(projectRoot, "package.json"),
|
|
44
|
-
JSON.stringify(pkg, null, 2)
|
|
45
|
-
);
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
if (!pkg.dependencies) {
|
|
50
|
+
pkg.dependencies = {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
pkg.dependencies["dinou"] = "file:./dinou";
|
|
54
|
+
|
|
55
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
56
|
+
|
|
57
|
+
function detectPackageManager() {
|
|
58
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
59
|
+
|
|
60
|
+
if (userAgent) {
|
|
61
|
+
if (userAgent.startsWith("yarn")) return "yarn";
|
|
62
|
+
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
63
|
+
if (userAgent.startsWith("bun")) return "bun";
|
|
64
|
+
if (userAgent.startsWith("npm")) return "npm";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (fs.existsSync(path.join(projectRoot, "yarn.lock"))) return "yarn";
|
|
68
|
+
if (fs.existsSync(path.join(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
|
|
69
|
+
if (fs.existsSync(path.join(projectRoot, "bun.lockb"))) return "bun";
|
|
70
|
+
if (fs.existsSync(path.join(projectRoot, "package-lock.json"))) return "npm";
|
|
71
|
+
|
|
72
|
+
return "npm";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const pm = detectPackageManager();
|
|
76
|
+
console.log(`🕵️ Package manager detected: ${pm}`);
|
|
77
|
+
|
|
78
|
+
// const installCommand = pm === "yarn" ? "yarn" : `${pm} install`;
|
|
79
|
+
const installCommand = `${pm} install`;
|
|
80
|
+
|
|
81
|
+
console.log(`📦 Executing '${installCommand}' to link dependencies...`);
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
execSync(installCommand, { stdio: "inherit", cwd: projectRoot });
|
|
85
|
+
console.log("✅ Dependencies updated successfully");
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(
|
|
88
|
+
`❌ Error on executing ${installCommand}. Please, install dependencies manually`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log(
|
|
93
|
+
"🎉 Eject completed successfully! Dinou is now running from local source.",
|
|
94
|
+
);
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dinou",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Modern Full-Stack React 19 framework with React Server Components, Server Functions, and Streaming SSR.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"dinou": "./cli.js"
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
|
-
".":
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dinou/index.mjs",
|
|
12
|
+
"require": "./dinou/index.js"
|
|
13
|
+
}
|
|
11
14
|
},
|
|
12
15
|
"types": "./dinou/index.d.ts",
|
|
13
16
|
"scripts": {
|