dinou 5.2.0 → 6.0.0
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 +16 -0
- package/README.md +3 -3
- package/dinou/core/cache-revalidate.js +5 -5
- package/dinou/core/generate-static-page.js +5 -5
- package/dinou/core/generate-static-pages.js +4 -4
- package/dinou/core/generate-static-rsc.js +3 -3
- package/dinou/core/generate-static-rscs.js +3 -3
- package/dinou/core/generate-static.js +2 -2
- package/dinou/core/generating-isg.js +3 -3
- package/dinou/core/get-asset-from-manifest.js +2 -2
- package/dinou/core/render-app-to-html.js +3 -3
- package/dinou/core/render-html.js +8 -8
- package/dinou/core/revalidating.js +39 -39
- package/dinou/core/server-function-proxy.js +1 -2
- package/dinou/core/server.js +18 -18
- package/dinou/esbuild/build.mjs +3 -3
- package/dinou/esbuild/dev.mjs +3 -3
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +2 -2
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +1 -1
- package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +1 -1
- package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +1 -1
- package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +1 -1
- package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +1 -1
- package/dinou/package.json +1 -1
- package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +1 -1
- package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +1 -1
- package/dinou/rollup/rollup.config.js +7 -7
- package/dinou/webpack/webpack.config.js +4 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ 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
|
+
## [6.0.0] - 2026-09-13
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **Unified `.dinou/` Directory for Build Artifacts & Manifests**: Relocated all compiler outputs, client/server bundles, and runtime metadata under a single `.dinou/` root directory instead of generating multiple folders across the project root.
|
|
12
|
+
* **Build Artifacts Relocation**:
|
|
13
|
+
- `dist2` (pre-rendered static & ISR HTML/RSC payloads) moved to `.dinou/dist2`
|
|
14
|
+
- `dist3` (production bundles & manifests) moved to `.dinou/dist3`
|
|
15
|
+
- `public` (development client bundles & compiled CSS) moved to `.dinou/public`
|
|
16
|
+
- `react_client_manifest` moved to `.dinou/react_client_manifest`
|
|
17
|
+
- `server_functions_manifest` moved to `.dinou/server_functions_manifest`
|
|
18
|
+
* **Clean Project Root & Improved DX**: Eliminates root-level clutter, giving projects a clean, minimal, and production-ready structure.
|
|
19
|
+
* **User Assets Isolation**: The root `public/` directory is now exclusively reserved for user static assets (images, favicons, fonts), preventing compiler bundles from mixing with user files.
|
|
20
|
+
* **Simplified `.gitignore`**: Projects now only require a single `.dinou/` entry in `.gitignore` instead of managing multiple build directory rules.
|
|
21
|
+
* **Effortless Cache Invalidation**: Wiping the compilation cache or performing clean builds can now be done in one command by deleting `.dinou/` (`rm -rf .dinou`).
|
|
22
|
+
* **Full Multi-Bundler Alignment**: Updated all Rollup, Esbuild, and Webpack compiler runners and custom manifest plugins to resolve into `.dinou/` seamlessly across development and production environments.
|
|
23
|
+
|
|
8
24
|
## [5.2.0] - 2026-07-13
|
|
9
25
|
|
|
10
26
|
### Added
|
package/README.md
CHANGED
|
@@ -1522,7 +1522,7 @@ Dinou is flexible and integrates with three major bundlers: **esbuild** (default
|
|
|
1522
1522
|
|
|
1523
1523
|
### Development
|
|
1524
1524
|
|
|
1525
|
-
Starts the development server with hot reloading. Files are emitted to the
|
|
1525
|
+
Starts the development server with hot reloading. Files are emitted to the `./dinou/public` folder.
|
|
1526
1526
|
|
|
1527
1527
|
| Command | Bundler | Description |
|
|
1528
1528
|
| :-------------------- | :---------- | :------------------------- |
|
|
@@ -1533,7 +1533,7 @@ Starts the development server with hot reloading. Files are emitted to the `publ
|
|
|
1533
1533
|
|
|
1534
1534
|
### Production Build
|
|
1535
1535
|
|
|
1536
|
-
Compiles the application for production. Files are emitted to the
|
|
1536
|
+
Compiles the application for production. Files are emitted to the `.dinou/dist3` folder.
|
|
1537
1537
|
|
|
1538
1538
|
| Command | Bundler |
|
|
1539
1539
|
| :---------------------- | :--------------------- |
|
|
@@ -1544,7 +1544,7 @@ Compiles the application for production. Files are emitted to the `dist3` folder
|
|
|
1544
1544
|
|
|
1545
1545
|
### Start Production Server
|
|
1546
1546
|
|
|
1547
|
-
Runs the built application from the
|
|
1547
|
+
Runs the built application from the `.dinou/dist3` folder.
|
|
1548
1548
|
|
|
1549
1549
|
| Command | Description |
|
|
1550
1550
|
| :---------------------- | :---------------------------------- |
|
|
@@ -39,7 +39,7 @@ async function revalidatePath(reqPath) {
|
|
|
39
39
|
if (referer) {
|
|
40
40
|
try {
|
|
41
41
|
currentPathname = new URL(referer).pathname;
|
|
42
|
-
} catch (e) {}
|
|
42
|
+
} catch (e) { }
|
|
43
43
|
} else {
|
|
44
44
|
currentPathname = ctx.req.path || "/";
|
|
45
45
|
}
|
|
@@ -55,7 +55,7 @@ async function revalidatePath(reqPath) {
|
|
|
55
55
|
cleanPath = cleanPath.slice(0, -1);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
const dist2Folder = path.resolve(process.cwd(), "dist2");
|
|
58
|
+
const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
|
|
59
59
|
const reqPathWithSlash = cleanPath.endsWith("/") ? cleanPath : cleanPath + "/";
|
|
60
60
|
|
|
61
61
|
// Check if there is an existing page to copy to _old
|
|
@@ -89,7 +89,7 @@ async function revalidatePath(reqPath) {
|
|
|
89
89
|
if (!rscResult.success) {
|
|
90
90
|
console.warn(`⚠️ [Revalidate] RSC generation failed for ${cleanPath}.`);
|
|
91
91
|
if (rscResult.tempPath && existsSync(rscResult.tempPath)) {
|
|
92
|
-
await fs.unlink(rscResult.tempPath).catch(() => {});
|
|
92
|
+
await fs.unlink(rscResult.tempPath).catch(() => { });
|
|
93
93
|
}
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
@@ -104,7 +104,7 @@ async function revalidatePath(reqPath) {
|
|
|
104
104
|
} else {
|
|
105
105
|
console.warn(`⚠️ [Revalidate] HTML generation failed for ${cleanPath}.`);
|
|
106
106
|
if (pageResult.tempPath && existsSync(pageResult.tempPath)) {
|
|
107
|
-
await fs.unlink(pageResult.tempPath).catch(() => {});
|
|
107
|
+
await fs.unlink(pageResult.tempPath).catch(() => { });
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
} catch (e) {
|
|
@@ -114,7 +114,7 @@ async function revalidatePath(reqPath) {
|
|
|
114
114
|
|
|
115
115
|
async function revalidateTag(tag) {
|
|
116
116
|
console.log(`[Revalidate] Starting on-demand revalidation for tag: "${tag}"...`);
|
|
117
|
-
const dist2Folder = path.resolve(process.cwd(), "dist2");
|
|
117
|
+
const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
|
|
118
118
|
if (!existsSync(dist2Folder)) return;
|
|
119
119
|
|
|
120
120
|
const metadataFiles = await walkMetadataFiles(dist2Folder);
|
|
@@ -5,7 +5,7 @@ const renderAppToHtml = require("./render-app-to-html.js");
|
|
|
5
5
|
const { getStaticMetadata } = require("./build-static-pages.js");
|
|
6
6
|
const { processMetadata } = require("./get-ssg-metadata.js");
|
|
7
7
|
|
|
8
|
-
const OUT_DIR = path.resolve("dist2");
|
|
8
|
+
const OUT_DIR = path.resolve(".dinou/dist2");
|
|
9
9
|
|
|
10
10
|
async function generateStaticPage(reqPath) {
|
|
11
11
|
const finalReqPath = reqPath.endsWith("/") ? reqPath : reqPath + "/";
|
|
@@ -52,9 +52,9 @@ async function generateStaticPage(reqPath) {
|
|
|
52
52
|
status: (code) => {
|
|
53
53
|
capturedStatus.value = code;
|
|
54
54
|
},
|
|
55
|
-
setHeader: () => {},
|
|
56
|
-
clearCookie: () => {},
|
|
57
|
-
redirect: () => {},
|
|
55
|
+
setHeader: () => { },
|
|
56
|
+
clearCookie: () => { },
|
|
57
|
+
redirect: () => { },
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
htmlStream = renderAppToHtml(
|
|
@@ -112,7 +112,7 @@ async function generateStaticPage(reqPath) {
|
|
|
112
112
|
status: status,
|
|
113
113
|
};
|
|
114
114
|
} catch (error) {
|
|
115
|
-
await fs.unlink(tempHtmlPath).catch(() => {});
|
|
115
|
+
await fs.unlink(tempHtmlPath).catch(() => { });
|
|
116
116
|
return { success: false, tempPath: tempHtmlPath };
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -7,7 +7,7 @@ const { getStaticMetadata } = require("./build-static-pages.js");
|
|
|
7
7
|
const { processMetadata } = require("./get-ssg-metadata.js");
|
|
8
8
|
const { updateStatus } = require("./status-manifest.js");
|
|
9
9
|
|
|
10
|
-
const OUT_DIR = path.resolve("dist2");
|
|
10
|
+
const OUT_DIR = path.resolve(".dinou/dist2");
|
|
11
11
|
|
|
12
12
|
async function generateStaticPages(routes) {
|
|
13
13
|
for (const route of routes) {
|
|
@@ -57,9 +57,9 @@ async function generateStaticPages(routes) {
|
|
|
57
57
|
console.warn(`[SSG] Status ${code} ignored for ${reqPath}`);
|
|
58
58
|
capturedStatus.value = code;
|
|
59
59
|
},
|
|
60
|
-
setHeader: () => {},
|
|
61
|
-
clearCookie: () => {},
|
|
62
|
-
redirect: () => {},
|
|
60
|
+
setHeader: () => { },
|
|
61
|
+
clearCookie: () => { },
|
|
62
|
+
redirect: () => { },
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
htmlStream = renderAppToHtml(
|
|
@@ -9,7 +9,7 @@ const { renderToPipeableStream } = isWebpack
|
|
|
9
9
|
: require("@roggc/react-server-dom-esm/server");
|
|
10
10
|
const { requestStorage } = require("./request-context.js");
|
|
11
11
|
|
|
12
|
-
const OUT_DIR = path.resolve("dist2");
|
|
12
|
+
const OUT_DIR = path.resolve(".dinou/dist2");
|
|
13
13
|
// const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
|
|
14
14
|
|
|
15
15
|
async function generateStaticRSC(reqPath) {
|
|
@@ -83,8 +83,8 @@ async function generateStaticRSC(reqPath) {
|
|
|
83
83
|
fs.readFileSync(
|
|
84
84
|
path.resolve(
|
|
85
85
|
isWebpack
|
|
86
|
-
? "dist3/react-client-manifest.json"
|
|
87
|
-
: "react_client_manifest/react-client-manifest.json"
|
|
86
|
+
? ".dinou/dist3/react-client-manifest.json"
|
|
87
|
+
: ".dinou/react_client_manifest/react-client-manifest.json"
|
|
88
88
|
),
|
|
89
89
|
"utf8"
|
|
90
90
|
)
|
|
@@ -11,7 +11,7 @@ const { renderToPipeableStream } = isWebpack
|
|
|
11
11
|
// 👇 Your context storage
|
|
12
12
|
const { requestStorage } = require("./request-context.js");
|
|
13
13
|
|
|
14
|
-
const OUT_DIR = path.resolve("dist2");
|
|
14
|
+
const OUT_DIR = path.resolve(".dinou/dist2");
|
|
15
15
|
// const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
|
|
16
16
|
|
|
17
17
|
async function generateStaticRSCs(routes) {
|
|
@@ -19,8 +19,8 @@ async function generateStaticRSCs(routes) {
|
|
|
19
19
|
fs.readFileSync(
|
|
20
20
|
path.resolve(
|
|
21
21
|
isWebpack
|
|
22
|
-
? "dist3/react-client-manifest.json"
|
|
23
|
-
: "react_client_manifest/react-client-manifest.json"
|
|
22
|
+
? ".dinou/dist3/react-client-manifest.json"
|
|
23
|
+
: ".dinou/react_client_manifest/react-client-manifest.json"
|
|
24
24
|
),
|
|
25
25
|
"utf8"
|
|
26
26
|
)
|
|
@@ -5,11 +5,11 @@ const generateStaticPages = require("./generate-static-pages");
|
|
|
5
5
|
const { buildStaticPages, getStaticPaths } = require("./build-static-pages");
|
|
6
6
|
|
|
7
7
|
async function generateStatic() {
|
|
8
|
-
const distFolder2 = path.resolve(process.cwd(), "dist2");
|
|
8
|
+
const distFolder2 = path.resolve(process.cwd(), ".dinou/dist2");
|
|
9
9
|
|
|
10
10
|
if (existsSync(distFolder2)) {
|
|
11
11
|
rmSync(distFolder2, { recursive: true, force: true });
|
|
12
|
-
console.log("Deleted existing dist2 folder");
|
|
12
|
+
console.log("Deleted existing .dinou/dist2 folder");
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
await buildStaticPages();
|
|
@@ -9,7 +9,7 @@ const { safeRename } = require("./safe-rename");
|
|
|
9
9
|
const { updateStatus } = require("./status-manifest");
|
|
10
10
|
|
|
11
11
|
function generatingISG(reqPath, isDynamicFromServer) {
|
|
12
|
-
const dist2Folder = path.resolve(process.cwd(), "dist2");
|
|
12
|
+
const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
|
|
13
13
|
// 1. Concurrency Protection
|
|
14
14
|
if (regenerating.has(reqPath)) return;
|
|
15
15
|
try {
|
|
@@ -45,7 +45,7 @@ function generatingISG(reqPath, isDynamicFromServer) {
|
|
|
45
45
|
const rscResult = await generateStaticRSC(reqPath);
|
|
46
46
|
if (!rscResult.success) {
|
|
47
47
|
console.warn(`⚠️ [ISG] RSC generation failed for ${reqPath}. Aborting.`);
|
|
48
|
-
await fs.unlink(rscResult.tempPath).catch(() => {});
|
|
48
|
+
await fs.unlink(rscResult.tempPath).catch(() => { });
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -59,7 +59,7 @@ function generatingISG(reqPath, isDynamicFromServer) {
|
|
|
59
59
|
isDynamicFromServer.value = false;
|
|
60
60
|
console.log(`✅ [ISG] Successfully promoted ${reqPath} to static.`);
|
|
61
61
|
} else {
|
|
62
|
-
await fs.unlink(pageResult.tempPath).catch(() => {});
|
|
62
|
+
await fs.unlink(pageResult.tempPath).catch(() => { });
|
|
63
63
|
console.warn(`⚠️ [ISG] HTML generation failed for ${reqPath}. Aborting commit.`);
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -7,13 +7,13 @@ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
|
|
|
7
7
|
|
|
8
8
|
function getAssetFromManifest(name) {
|
|
9
9
|
if (process.env.NODE_ENV === "production" && !read) {
|
|
10
|
-
const manifestPath = path.resolve(process.cwd(), "dist3/manifest.json");
|
|
10
|
+
const manifestPath = path.resolve(process.cwd(), ".dinou/dist3/manifest.json");
|
|
11
11
|
if (fs.existsSync(manifestPath)) {
|
|
12
12
|
manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
13
13
|
read = true;
|
|
14
14
|
}
|
|
15
15
|
} else if (isWebpack && !read) {
|
|
16
|
-
const manifestPath = path.resolve(process.cwd(), "public/manifest.json");
|
|
16
|
+
const manifestPath = path.resolve(process.cwd(), ".dinou/public/manifest.json");
|
|
17
17
|
if (fs.existsSync(manifestPath)) {
|
|
18
18
|
manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
19
19
|
read = true;
|
|
@@ -15,8 +15,8 @@ const { renderToPipeableStream } = isWebpack
|
|
|
15
15
|
const manifestPath = path.resolve(
|
|
16
16
|
process.cwd(),
|
|
17
17
|
isWebpack
|
|
18
|
-
? (isDevelopment ? "public/react-client-manifest.json" : "dist3/react-client-manifest.json")
|
|
19
|
-
: "react_client_manifest/react-client-manifest.json"
|
|
18
|
+
? (isDevelopment ? ".dinou/public/react-client-manifest.json" : ".dinou/dist3/react-client-manifest.json")
|
|
19
|
+
: ".dinou/react_client_manifest/react-client-manifest.json"
|
|
20
20
|
);
|
|
21
21
|
|
|
22
22
|
let cachedManifest = null;
|
|
@@ -189,7 +189,7 @@ function renderAppToHtml(
|
|
|
189
189
|
);
|
|
190
190
|
|
|
191
191
|
const query = JSON.parse(paramsString || "{}");
|
|
192
|
-
const rscPath = path.resolve(process.cwd(), "dist2", reqPath.replace(/^\//, ""), "rsc.rsc");
|
|
192
|
+
const rscPath = path.resolve(process.cwd(), ".dinou/dist2", reqPath.replace(/^\//, ""), "rsc.rsc");
|
|
193
193
|
const hasStaticRsc = !isDynamic && fs.existsSync(rscPath);
|
|
194
194
|
|
|
195
195
|
if (hasStaticRsc) {
|
|
@@ -144,7 +144,7 @@ function getImportMapHtml() {
|
|
|
144
144
|
|
|
145
145
|
const manifestPath = path.resolve(
|
|
146
146
|
process.cwd(),
|
|
147
|
-
"react_client_manifest/react-client-manifest.json"
|
|
147
|
+
".dinou/react_client_manifest/react-client-manifest.json"
|
|
148
148
|
);
|
|
149
149
|
|
|
150
150
|
if (!fs.existsSync(manifestPath)) {
|
|
@@ -184,11 +184,11 @@ function getSsrManifest() {
|
|
|
184
184
|
const path = require("path");
|
|
185
185
|
const ssrManifestPath = path.resolve(
|
|
186
186
|
process.cwd(),
|
|
187
|
-
isDevelopment ? "public/react-ssr-manifest.json" : "dist3/react-ssr-manifest.json"
|
|
187
|
+
isDevelopment ? ".dinou/public/react-ssr-manifest.json" : ".dinou/dist3/react-ssr-manifest.json"
|
|
188
188
|
);
|
|
189
189
|
const clientManifestPath = path.resolve(
|
|
190
190
|
process.cwd(),
|
|
191
|
-
isDevelopment ? "public/react-client-manifest.json" : "dist3/react-client-manifest.json"
|
|
191
|
+
isDevelopment ? ".dinou/public/react-client-manifest.json" : ".dinou/dist3/react-client-manifest.json"
|
|
192
192
|
);
|
|
193
193
|
|
|
194
194
|
const ssrContent = fs.readFileSync(ssrManifestPath, "utf8");
|
|
@@ -204,7 +204,7 @@ function getSsrManifest() {
|
|
|
204
204
|
if (entry && entry.id !== undefined) {
|
|
205
205
|
try {
|
|
206
206
|
requireMap[entry.id] = fileURLToPath(fileUrl);
|
|
207
|
-
} catch {}
|
|
207
|
+
} catch { }
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
global.__webpack_require_map__ = requireMap;
|
|
@@ -294,10 +294,10 @@ async function renderToStream(
|
|
|
294
294
|
const errorStream = renderToPipeableStream(errorJSX, {
|
|
295
295
|
onShellReady() {
|
|
296
296
|
const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
297
|
+
if (!isWebpack) {
|
|
298
|
+
const importMapHtml = getImportMapHtml();
|
|
299
|
+
process.stdout.write(importMapHtml);
|
|
300
|
+
}
|
|
301
301
|
errorStream.pipe(process.stdout);
|
|
302
302
|
},
|
|
303
303
|
onError(err) {
|
|
@@ -10,7 +10,7 @@ const { updateStatus } = require("./status-manifest");
|
|
|
10
10
|
const regenerating = new Set();
|
|
11
11
|
|
|
12
12
|
function revalidating(reqPath, isDynamicFromServer) {
|
|
13
|
-
const dist2Folder = path.resolve(process.cwd(), "dist2");
|
|
13
|
+
const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
|
|
14
14
|
const metadataPath = path.join(dist2Folder, reqPath, "metadata.json");
|
|
15
15
|
|
|
16
16
|
if (regenerating.has(reqPath)) return;
|
|
@@ -46,49 +46,49 @@ function revalidating(reqPath, isDynamicFromServer) {
|
|
|
46
46
|
(async () => {
|
|
47
47
|
try {
|
|
48
48
|
console.log(`[ISR] Starting regeneration for ${reqPath}...`);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const isDynamic = {};
|
|
50
|
+
await buildStaticPage(reqPath, isDynamic);
|
|
51
|
+
if (isDynamic.value) {
|
|
52
|
+
isDynamicFromServer.value = true;
|
|
53
|
+
console.log(
|
|
54
|
+
`[ISR] Bailout detected for ${reqPath}. Switching to Dynamic.`
|
|
55
|
+
);
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
const rscResult = await generateStaticRSC(reqPath);
|
|
61
|
+
if (!rscResult.success) {
|
|
62
|
+
console.warn(`⚠️ [ISR] RSC generation failed for ${reqPath}. Aborting.`);
|
|
63
|
+
await fs.unlink(rscResult.tempPath).catch(() => { });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
// Commit the RSC payload immediately so that generateStaticPage can read it
|
|
68
|
+
await safeRename(rscResult.tempPath, rscResult.finalPath);
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
70
|
+
const pageResult = await generateStaticPage(reqPath);
|
|
71
|
+
if (pageResult.success) {
|
|
72
|
+
await safeRename(pageResult.tempPath, pageResult.finalPath);
|
|
73
|
+
updateStatus(reqPath, pageResult.status);
|
|
74
|
+
isDynamicFromServer.value = false;
|
|
75
|
+
console.log(
|
|
76
|
+
`✅ [ISR] Successfully committed ${reqPath} (Status: ${pageResult.status})`
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
console.warn(
|
|
80
|
+
`⚠️ [ISR] HTML generation failed for ${reqPath}. Aborting commit.`
|
|
81
|
+
);
|
|
82
|
+
await fs.unlink(pageResult.tempPath).catch(() => { });
|
|
83
|
+
}
|
|
84
|
+
} catch (e) {
|
|
85
|
+
console.error(`[ISR] Critical error regenerating ${reqPath}:`, e);
|
|
86
|
+
} finally {
|
|
87
|
+
regenerating.delete(reqPath);
|
|
88
|
+
}
|
|
89
|
+
})();
|
|
88
90
|
}
|
|
89
|
-
})();
|
|
90
|
-
}
|
|
91
|
-
}).catch((err) => {});
|
|
91
|
+
}).catch((err) => { });
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
module.exports = { revalidating, regenerating };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// public/server-function-proxy.js
|
|
2
1
|
import { createFromFetch } from "@roggc/react-server-dom-esm/client";
|
|
3
2
|
|
|
4
3
|
function isSafeRedirect(url) {
|
|
@@ -16,7 +15,7 @@ function executeRedirect(url) {
|
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export function createServerFunctionProxy(id) {
|
|
19
|
-
return new Proxy(() => {}, {
|
|
18
|
+
return new Proxy(() => { }, {
|
|
20
19
|
apply: async (_target, _thisArg, args) => {
|
|
21
20
|
let body;
|
|
22
21
|
const headers = {
|
package/dinou/core/server.js
CHANGED
|
@@ -87,7 +87,7 @@ if (existsSync(dinouConfigPath)) {
|
|
|
87
87
|
const renderAppToHtml = require("./render-app-to-html.js");
|
|
88
88
|
const { revalidating, regenerating } = require("./revalidating.js");
|
|
89
89
|
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
90
|
-
const outputFolder = isDevelopment ? "public" : "dist3";
|
|
90
|
+
const outputFolder = isDevelopment ? ".dinou/public" : ".dinou/dist3";
|
|
91
91
|
const chokidar = require("chokidar");
|
|
92
92
|
const { fileURLToPath, pathToFileURL } = require("url");
|
|
93
93
|
const parseExports = require("./parse-exports.js");
|
|
@@ -101,11 +101,11 @@ if (isDevelopment) {
|
|
|
101
101
|
process.cwd(),
|
|
102
102
|
isWebpack
|
|
103
103
|
? `${outputFolder}/react-client-manifest.json`
|
|
104
|
-
:
|
|
104
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
105
105
|
);
|
|
106
106
|
const manifestFolderPath = path.resolve(
|
|
107
107
|
process.cwd(),
|
|
108
|
-
isWebpack ? outputFolder : "react_client_manifest",
|
|
108
|
+
isWebpack ? outputFolder : ".dinou/react_client_manifest",
|
|
109
109
|
);
|
|
110
110
|
|
|
111
111
|
let manifestWatcher = null;
|
|
@@ -278,7 +278,7 @@ if (!isDevelopment) {
|
|
|
278
278
|
process.cwd(),
|
|
279
279
|
isWebpack
|
|
280
280
|
? `${outputFolder}/server-functions-manifest.json`
|
|
281
|
-
:
|
|
281
|
+
: `.dinou/server_functions_manifest/server-functions-manifest.json`,
|
|
282
282
|
); // Adjust 'dist/' to your outdir
|
|
283
283
|
if (existsSync(manifestPath)) {
|
|
284
284
|
serverFunctionsManifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
@@ -598,7 +598,7 @@ const clientManifestResolvedPath = path.resolve(
|
|
|
598
598
|
process.cwd(),
|
|
599
599
|
isWebpack
|
|
600
600
|
? `${outputFolder}/react-client-manifest.json`
|
|
601
|
-
:
|
|
601
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
602
602
|
);
|
|
603
603
|
|
|
604
604
|
function isManifestReady() {
|
|
@@ -638,7 +638,7 @@ if (!isDevelopment) {
|
|
|
638
638
|
process.cwd(),
|
|
639
639
|
isWebpack
|
|
640
640
|
? `${outputFolder}/react-client-manifest.json`
|
|
641
|
-
:
|
|
641
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
642
642
|
),
|
|
643
643
|
"utf8",
|
|
644
644
|
),
|
|
@@ -679,7 +679,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
679
679
|
if ((!isDevelopment && !dynamicState.value) || isStatic) {
|
|
680
680
|
let currentGeneratedAt = null;
|
|
681
681
|
try {
|
|
682
|
-
const metadataPath = path.join("dist2", reqPath, "metadata.json");
|
|
682
|
+
const metadataPath = path.join(".dinou/dist2", reqPath, "metadata.json");
|
|
683
683
|
if (existsSync(metadataPath)) {
|
|
684
684
|
const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
|
|
685
685
|
currentGeneratedAt = metaObj.generatedAt || null;
|
|
@@ -694,12 +694,12 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
694
694
|
req.query.buildId !== String(currentGeneratedAt));
|
|
695
695
|
|
|
696
696
|
const payloadPath = path.resolve(
|
|
697
|
-
"dist2",
|
|
697
|
+
".dinou/dist2",
|
|
698
698
|
reqPath.replace(/^\//, ""),
|
|
699
699
|
useOld ? "rsc._old.rsc" : "rsc.rsc",
|
|
700
700
|
);
|
|
701
701
|
|
|
702
|
-
const distDir = path.resolve("dist2");
|
|
702
|
+
const distDir = path.resolve(".dinou/dist2");
|
|
703
703
|
|
|
704
704
|
if (!payloadPath.startsWith(distDir)) {
|
|
705
705
|
return res.status(403).end();
|
|
@@ -803,7 +803,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
803
803
|
if (isDevelopment) {
|
|
804
804
|
isPathBlocked = true;
|
|
805
805
|
} else {
|
|
806
|
-
const htmlPath = path.join("dist2", reqPath, "index.html");
|
|
806
|
+
const htmlPath = path.join(".dinou/dist2", reqPath, "index.html");
|
|
807
807
|
if (!existsSync(htmlPath)) {
|
|
808
808
|
isPathBlocked = true;
|
|
809
809
|
}
|
|
@@ -839,7 +839,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
839
839
|
process.cwd(),
|
|
840
840
|
isWebpack
|
|
841
841
|
? `${outputFolder}/react-client-manifest.json`
|
|
842
|
-
:
|
|
842
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
843
843
|
),
|
|
844
844
|
"utf8",
|
|
845
845
|
),
|
|
@@ -874,7 +874,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
874
874
|
process.cwd(),
|
|
875
875
|
isWebpack
|
|
876
876
|
? `${outputFolder}/react-client-manifest.json`
|
|
877
|
-
:
|
|
877
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
878
878
|
),
|
|
879
879
|
"utf8",
|
|
880
880
|
),
|
|
@@ -930,7 +930,7 @@ app.post(/^\/____rsc_payload_error____\/.*\/?$/, async (req, res) => {
|
|
|
930
930
|
process.cwd(),
|
|
931
931
|
isWebpack
|
|
932
932
|
? `${outputFolder}/react-client-manifest.json`
|
|
933
|
-
:
|
|
933
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
934
934
|
),
|
|
935
935
|
"utf8",
|
|
936
936
|
),
|
|
@@ -1045,7 +1045,7 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
1045
1045
|
if (isDevelopment) {
|
|
1046
1046
|
isPathBlocked = true;
|
|
1047
1047
|
} else {
|
|
1048
|
-
const htmlPath = path.join("dist2", req.path, "index.html");
|
|
1048
|
+
const htmlPath = path.join(".dinou/dist2", req.path, "index.html");
|
|
1049
1049
|
if (!existsSync(htmlPath)) {
|
|
1050
1050
|
isPathBlocked = true;
|
|
1051
1051
|
}
|
|
@@ -1072,9 +1072,9 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
1072
1072
|
let htmlPathOld;
|
|
1073
1073
|
if (regenerating.has(reqPath)) {
|
|
1074
1074
|
// Still regenerating, serve old HTML if exists
|
|
1075
|
-
htmlPathOld = path.join("dist2", reqPath, "index._old.html");
|
|
1075
|
+
htmlPathOld = path.join(".dinou/dist2", reqPath, "index._old.html");
|
|
1076
1076
|
}
|
|
1077
|
-
const htmlPath = path.join("dist2", reqPath, "index.html");
|
|
1077
|
+
const htmlPath = path.join(".dinou/dist2", reqPath, "index.html");
|
|
1078
1078
|
// Decide which file to read
|
|
1079
1079
|
const fileToRead = htmlPathOld || htmlPath;
|
|
1080
1080
|
|
|
@@ -1092,7 +1092,7 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
1092
1092
|
let htmlContent = readFileSync(fileToRead, "utf8");
|
|
1093
1093
|
let buildId = "";
|
|
1094
1094
|
try {
|
|
1095
|
-
const metadataPath = path.join("dist2", reqPath, "metadata.json");
|
|
1095
|
+
const metadataPath = path.join(".dinou/dist2", reqPath, "metadata.json");
|
|
1096
1096
|
if (existsSync(metadataPath)) {
|
|
1097
1097
|
const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
|
|
1098
1098
|
buildId = metaObj.generatedAt || "";
|
|
@@ -1463,7 +1463,7 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
1463
1463
|
process.cwd(),
|
|
1464
1464
|
isWebpack
|
|
1465
1465
|
? `${outputFolder}/react-client-manifest.json`
|
|
1466
|
-
:
|
|
1466
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
1467
1467
|
);
|
|
1468
1468
|
// Verify that the manifest exists to avoid errors
|
|
1469
1469
|
if (!existsSync(manifestPath)) {
|
package/dinou/esbuild/build.mjs
CHANGED
|
@@ -9,10 +9,10 @@ import { updateManifestForModule } from "./helpers-esbuild/update-manifest-for-m
|
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = path.dirname(__filename);
|
|
11
11
|
|
|
12
|
-
const outdir = "dist3";
|
|
12
|
+
const outdir = ".dinou/dist3";
|
|
13
13
|
await fs.rm(outdir, { recursive: true, force: true });
|
|
14
|
-
await fs.rm("react_client_manifest", { recursive: true, force: true });
|
|
15
|
-
await fs.rm("server_functions_manifest", { recursive: true, force: true });
|
|
14
|
+
await fs.rm(".dinou/react_client_manifest", { recursive: true, force: true });
|
|
15
|
+
await fs.rm(".dinou/server_functions_manifest", { recursive: true, force: true });
|
|
16
16
|
|
|
17
17
|
const absPathToClientRedirect = path.resolve(
|
|
18
18
|
__dirname,
|
package/dinou/esbuild/dev.mjs
CHANGED
|
@@ -13,10 +13,10 @@ import { useServerRegex } from "../constants.js";
|
|
|
13
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
14
|
const __dirname = path.dirname(__filename);
|
|
15
15
|
|
|
16
|
-
const outdir = "public";
|
|
16
|
+
const outdir = ".dinou/public";
|
|
17
17
|
await fs.rm(outdir, { recursive: true, force: true });
|
|
18
|
-
await fs.rm("react_client_manifest", { recursive: true, force: true });
|
|
19
|
-
await fs.rm("server_functions_manifest", { recursive: true, force: true });
|
|
18
|
+
await fs.rm(".dinou/react_client_manifest", { recursive: true, force: true });
|
|
19
|
+
await fs.rm(".dinou/server_functions_manifest", { recursive: true, force: true });
|
|
20
20
|
|
|
21
21
|
let currentCtx = null; // Track the active esbuild context
|
|
22
22
|
let debounceTimer = null; // For debouncing recreations
|
|
@@ -13,7 +13,7 @@ const manifestData = {};
|
|
|
13
13
|
|
|
14
14
|
export default function getConfigEsbuildProd({
|
|
15
15
|
entryPoints,
|
|
16
|
-
outdir = "dist3",
|
|
16
|
+
outdir = ".dinou/dist3",
|
|
17
17
|
manifest = {},
|
|
18
18
|
}) {
|
|
19
19
|
let plugins = [
|
|
@@ -22,7 +22,7 @@ export default function getConfigEsbuildProd({
|
|
|
22
22
|
cssProcessorPlugin({ outdir }),
|
|
23
23
|
reactClientManifestPlugin({
|
|
24
24
|
manifest,
|
|
25
|
-
manifestPath:
|
|
25
|
+
manifestPath: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
26
26
|
}),
|
|
27
27
|
assetsPlugin(),
|
|
28
28
|
manifestGeneratorPlugin(manifestData),
|
|
@@ -11,7 +11,7 @@ import { pathToFileURL } from "node:url";
|
|
|
11
11
|
import resolve from "resolve";
|
|
12
12
|
import createPostCSSExtractPlugin from "../plugins-postcss/postcss-extract-plugin.js";
|
|
13
13
|
|
|
14
|
-
export default function cssProcessorPlugin({ outdir = "public" } = {}) {
|
|
14
|
+
export default function cssProcessorPlugin({ outdir = ".dinou/public" } = {}) {
|
|
15
15
|
const { finalize, plugin: extractor } = createPostCSSExtractPlugin({
|
|
16
16
|
outputFile: `${outdir}/styles.css`,
|
|
17
17
|
});
|
|
@@ -7,7 +7,7 @@ import parseExports from "../../core/parse-exports.js";
|
|
|
7
7
|
import { useClientRegex } from "../../constants.js";
|
|
8
8
|
|
|
9
9
|
export default function reactClientManifestPlugin({
|
|
10
|
-
manifestPath = "react_client_manifest/react-client-manifest.json",
|
|
10
|
+
manifestPath = ".dinou/react_client_manifest/react-client-manifest.json",
|
|
11
11
|
manifest = {},
|
|
12
12
|
} = {}) {
|
|
13
13
|
return {
|
|
@@ -77,7 +77,7 @@ export default function serverFunctionsPlugin(manifestData = {}) {
|
|
|
77
77
|
|
|
78
78
|
// Write the server functions manifest JSON file to the output directory
|
|
79
79
|
const manifestPath = path.join(
|
|
80
|
-
"server_functions_manifest",
|
|
80
|
+
".dinou/server_functions_manifest",
|
|
81
81
|
"server-functions-manifest.json"
|
|
82
82
|
);
|
|
83
83
|
await fs.mkdir(path.dirname(manifestPath), { recursive: true });
|
|
@@ -20,7 +20,7 @@ export default function esmHmrPlugin({
|
|
|
20
20
|
name: "esm-hmr",
|
|
21
21
|
|
|
22
22
|
setup(build) {
|
|
23
|
-
const outdir = build.initialOptions.outdir || "public";
|
|
23
|
+
const outdir = build.initialOptions.outdir || ".dinou/public";
|
|
24
24
|
const entryPoints = build.initialOptions.entryPoints;
|
|
25
25
|
|
|
26
26
|
const entrySources = [];
|
package/dinou/package.json
CHANGED
|
@@ -39,7 +39,7 @@ function getDefaultExportName(code) {
|
|
|
39
39
|
|
|
40
40
|
function reactClientManifestPlugin({
|
|
41
41
|
srcDir = path.resolve("src"),
|
|
42
|
-
manifestPath = "react_client_manifest/react-client-manifest.json",
|
|
42
|
+
manifestPath = ".dinou/react_client_manifest/react-client-manifest.json",
|
|
43
43
|
assetInclude = regex,
|
|
44
44
|
} = {}) {
|
|
45
45
|
const manifest = {};
|
|
@@ -71,7 +71,7 @@ function serverFunctionsPlugin() {
|
|
|
71
71
|
|
|
72
72
|
// Write the manifest to the specified folder (e.g. same place as other assets)
|
|
73
73
|
const manifestPath = path.join(
|
|
74
|
-
"server_functions_manifest",
|
|
74
|
+
".dinou/server_functions_manifest",
|
|
75
75
|
"server-functions-manifest.json"
|
|
76
76
|
);
|
|
77
77
|
try {
|
|
@@ -18,7 +18,7 @@ const { regex } = require("../core/asset-extensions.js");
|
|
|
18
18
|
const manifestGeneratorPlugin = require("./rollup-plugins/manifest-generator-plugin.js");
|
|
19
19
|
|
|
20
20
|
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
21
|
-
const outputDirectory = isDevelopment ? "public" : "dist3";
|
|
21
|
+
const outputDirectory = isDevelopment ? ".dinou/public" : ".dinou/dist3";
|
|
22
22
|
|
|
23
23
|
const localDinouPath = path.resolve(process.cwd(), "dinou");
|
|
24
24
|
const isEjected = fs.existsSync(localDinouPath);
|
|
@@ -96,8 +96,8 @@ module.exports = async function () {
|
|
|
96
96
|
del({
|
|
97
97
|
targets: [
|
|
98
98
|
`${outputDirectory}/*`,
|
|
99
|
-
"react_client_manifest/*",
|
|
100
|
-
"server_functions_manifest/*",
|
|
99
|
+
".dinou/react_client_manifest/*",
|
|
100
|
+
".dinou/server_functions_manifest/*",
|
|
101
101
|
],
|
|
102
102
|
runOnce: true,
|
|
103
103
|
hook: "buildStart",
|
|
@@ -157,7 +157,7 @@ module.exports = async function () {
|
|
|
157
157
|
}),
|
|
158
158
|
reactClientManifest({
|
|
159
159
|
manifestPath: path.join(
|
|
160
|
-
"react_client_manifest",
|
|
160
|
+
".dinou/react_client_manifest",
|
|
161
161
|
"react-client-manifest.json",
|
|
162
162
|
),
|
|
163
163
|
}),
|
|
@@ -168,9 +168,9 @@ module.exports = async function () {
|
|
|
168
168
|
].filter(Boolean),
|
|
169
169
|
watch: {
|
|
170
170
|
exclude: [
|
|
171
|
-
"public/**",
|
|
172
|
-
"react_client_manifest/**",
|
|
173
|
-
"server_functions_manifest/**",
|
|
171
|
+
".dinou/public/**",
|
|
172
|
+
".dinou/react_client_manifest/**",
|
|
173
|
+
".dinou/server_functions_manifest/**",
|
|
174
174
|
],
|
|
175
175
|
},
|
|
176
176
|
onwarn(warning, warn) {
|
|
@@ -13,7 +13,7 @@ const { regex } = require("../core/asset-extensions");
|
|
|
13
13
|
const getCSSEntries = require("./helpers/get-webpack-entries");
|
|
14
14
|
|
|
15
15
|
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
16
|
-
const outputDirectory = isDevelopment ? "public" : "dist3";
|
|
16
|
+
const outputDirectory = isDevelopment ? ".dinou/public" : ".dinou/dist3";
|
|
17
17
|
|
|
18
18
|
function getConfigFileIfExists() {
|
|
19
19
|
const tsconfigPath = path.resolve(process.cwd(), "tsconfig.json");
|
|
@@ -39,8 +39,8 @@ console.log(
|
|
|
39
39
|
const projectRoot = process.cwd();
|
|
40
40
|
|
|
41
41
|
const outputDirs = [
|
|
42
|
-
path.resolve(projectRoot, "public"),
|
|
43
|
-
path.resolve(projectRoot, "dist3"),
|
|
42
|
+
path.resolve(projectRoot, ".dinou/public"),
|
|
43
|
+
path.resolve(projectRoot, ".dinou/dist3"),
|
|
44
44
|
];
|
|
45
45
|
|
|
46
46
|
function cleanDir(dir) {
|
|
@@ -54,7 +54,7 @@ function cleanDir(dir) {
|
|
|
54
54
|
} catch (e) {
|
|
55
55
|
try {
|
|
56
56
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
57
|
-
} catch (err) {}
|
|
57
|
+
} catch (err) { }
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dinou",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Lightweight-Ejectable Full-Stack React 19 Framework with support for React Server Components (RSC), Server Functions, Server-Side Rendering (SSR), Static Generation (SSG), Incremental Static Generation (ISG), and Incremental Static Regeneration (ISR)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|