dinou 5.1.2 → 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 +29 -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/navigation.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-webpack.js +7 -3
- package/dinou/core/server-function-proxy.js +8 -5
- package/dinou/core/server.js +105 -24
- 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,35 @@ 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
|
+
|
|
24
|
+
## [5.2.0] - 2026-07-13
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- **Lightweight Plugin System & `dinou.config.js` support**: Added native support for extending the framework without manually modifying the core Express server.
|
|
28
|
+
* **Config Loader**: Automatically loads a `dinou.config.js` file at the root of the project to initialize custom plugins.
|
|
29
|
+
* **`onServerInit(app)` Hook**: Allows plugins to register global Express middlewares, custom endpoints (like webhooks), or API routes.
|
|
30
|
+
* **`onRequestContext(req, res, context)` Hook**: Allows plugins to inject custom properties (like `locale` or `userId`) into the RSC context across standard page requests, Server Actions, and dynamic compilation child processes.
|
|
31
|
+
* **Try-Catch Isolation**: Wrapped plugin hooks in safe boundaries with named logging to prevent third-party plugin errors from crashing the server.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- **URL resolution for search params**: Fixed `useSearchParams` and `usePathname` to work correctly with URL hashes.
|
|
35
|
+
- **Server Actions with FormData**: Fixed server actions to correctly handle FormData arguments, supporting formData in any position in the args list.
|
|
36
|
+
|
|
8
37
|
## [5.1.2] - 2026-07-12
|
|
9
38
|
|
|
10
39
|
### Fixed
|
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;
|
package/dinou/core/navigation.js
CHANGED
|
@@ -126,7 +126,7 @@ export function usePathname() {
|
|
|
126
126
|
return "";
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
const path = fullRoute.split("?")[0];
|
|
129
|
+
const path = fullRoute.split("#")[0].split("?")[0];
|
|
130
130
|
return normalizePath(path);
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -165,6 +165,6 @@ export function useSearchParams() {
|
|
|
165
165
|
|
|
166
166
|
if (typeof fullRoute !== "string") return new URLSearchParams();
|
|
167
167
|
|
|
168
|
-
const searchPart = fullRoute.split("?")[1] || "";
|
|
168
|
+
const searchPart = (fullRoute.split("?")[1] || "").split("#")[0];
|
|
169
169
|
return new URLSearchParams(searchPart);
|
|
170
170
|
}
|
|
@@ -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 };
|
|
@@ -22,13 +22,17 @@ function createServerFunctionProxy(id) {
|
|
|
22
22
|
"x-server-function-call": "1",
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const formDataIndex = args.findIndex((arg) => arg instanceof FormData);
|
|
26
|
+
|
|
27
|
+
if (formDataIndex !== -1) {
|
|
28
|
+
const formData = args[formDataIndex];
|
|
27
29
|
|
|
28
30
|
formData.append("__dinou_func_id", id);
|
|
31
|
+
formData.append("__dinou_formData_index", String(formDataIndex));
|
|
29
32
|
|
|
30
33
|
if (args.length > 1) {
|
|
31
|
-
|
|
34
|
+
const serializedArgs = args.map((arg, i) => (i === formDataIndex ? null : arg));
|
|
35
|
+
formData.append("__dinou_args", JSON.stringify(serializedArgs));
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
body = formData;
|
|
@@ -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,20 +15,24 @@ 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 = {
|
|
23
22
|
"x-server-function-call": "1",
|
|
24
23
|
};
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const formDataIndex = args.findIndex((arg) => arg instanceof FormData);
|
|
26
|
+
|
|
27
|
+
if (formDataIndex !== -1) {
|
|
28
|
+
const formData = args[formDataIndex];
|
|
28
29
|
|
|
29
30
|
formData.append("__dinou_func_id", id);
|
|
31
|
+
formData.append("__dinou_formData_index", String(formDataIndex));
|
|
30
32
|
|
|
31
33
|
if (args.length > 1) {
|
|
32
|
-
|
|
34
|
+
const serializedArgs = args.map((arg, i) => (i === formDataIndex ? null : arg));
|
|
35
|
+
formData.append("__dinou_args", JSON.stringify(serializedArgs));
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
body = formData;
|
package/dinou/core/server.js
CHANGED
|
@@ -72,10 +72,22 @@ addHook({
|
|
|
72
72
|
});
|
|
73
73
|
const importModule = require("./import-module");
|
|
74
74
|
const generateStatic = require("./generate-static.js");
|
|
75
|
+
|
|
76
|
+
// Load Dinou configuration and plugins
|
|
77
|
+
let dinouConfig = { plugins: [] };
|
|
78
|
+
const dinouConfigPath = path.resolve(process.cwd(), "dinou.config.js");
|
|
79
|
+
if (existsSync(dinouConfigPath)) {
|
|
80
|
+
try {
|
|
81
|
+
dinouConfig = require(dinouConfigPath);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error("[Dinou] Error loading dinou.config.js:", err);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
75
87
|
const renderAppToHtml = require("./render-app-to-html.js");
|
|
76
88
|
const { revalidating, regenerating } = require("./revalidating.js");
|
|
77
89
|
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
78
|
-
const outputFolder = isDevelopment ? "public" : "dist3";
|
|
90
|
+
const outputFolder = isDevelopment ? ".dinou/public" : ".dinou/dist3";
|
|
79
91
|
const chokidar = require("chokidar");
|
|
80
92
|
const { fileURLToPath, pathToFileURL } = require("url");
|
|
81
93
|
const parseExports = require("./parse-exports.js");
|
|
@@ -89,11 +101,11 @@ if (isDevelopment) {
|
|
|
89
101
|
process.cwd(),
|
|
90
102
|
isWebpack
|
|
91
103
|
? `${outputFolder}/react-client-manifest.json`
|
|
92
|
-
:
|
|
104
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
93
105
|
);
|
|
94
106
|
const manifestFolderPath = path.resolve(
|
|
95
107
|
process.cwd(),
|
|
96
|
-
isWebpack ? outputFolder : "react_client_manifest",
|
|
108
|
+
isWebpack ? outputFolder : ".dinou/react_client_manifest",
|
|
97
109
|
);
|
|
98
110
|
|
|
99
111
|
let manifestWatcher = null;
|
|
@@ -266,7 +278,7 @@ if (!isDevelopment) {
|
|
|
266
278
|
process.cwd(),
|
|
267
279
|
isWebpack
|
|
268
280
|
? `${outputFolder}/server-functions-manifest.json`
|
|
269
|
-
:
|
|
281
|
+
: `.dinou/server_functions_manifest/server-functions-manifest.json`,
|
|
270
282
|
); // Adjust 'dist/' to your outdir
|
|
271
283
|
if (existsSync(manifestPath)) {
|
|
272
284
|
serverFunctionsManifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
@@ -283,6 +295,21 @@ const cookieParser = require("cookie-parser");
|
|
|
283
295
|
const appUseCookieParser = cookieParser();
|
|
284
296
|
const app = express();
|
|
285
297
|
app.use(appUseCookieParser);
|
|
298
|
+
|
|
299
|
+
// Run plugins onServerInit hook
|
|
300
|
+
if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
|
|
301
|
+
for (const plugin of dinouConfig.plugins) {
|
|
302
|
+
if (typeof plugin.onServerInit === "function") {
|
|
303
|
+
try {
|
|
304
|
+
plugin.onServerInit(app);
|
|
305
|
+
console.log(`[Dinou] Plugin initialized: "${plugin.name || "unnamed"}"`);
|
|
306
|
+
} catch (err) {
|
|
307
|
+
console.error(`[Dinou] Error initializing plugin "${plugin.name || "unnamed"}":`, err);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
286
313
|
app.use(express.json());
|
|
287
314
|
|
|
288
315
|
// ============================================================
|
|
@@ -406,6 +433,20 @@ function getContext(req, res) {
|
|
|
406
433
|
redirect: (...args) => safeResCall("redirect", ...args),
|
|
407
434
|
},
|
|
408
435
|
};
|
|
436
|
+
|
|
437
|
+
// Run plugins onRequestContext hook
|
|
438
|
+
if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
|
|
439
|
+
for (const plugin of dinouConfig.plugins) {
|
|
440
|
+
if (typeof plugin.onRequestContext === "function") {
|
|
441
|
+
try {
|
|
442
|
+
plugin.onRequestContext(req, res, context);
|
|
443
|
+
} catch (err) {
|
|
444
|
+
console.error(`[Dinou] Error running onRequestContext in plugin "${plugin.name || "unnamed"}":`, err);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
409
450
|
return context;
|
|
410
451
|
}
|
|
411
452
|
|
|
@@ -534,6 +575,20 @@ function getContextForServerFunctionEndpoint(req, res) {
|
|
|
534
575
|
},
|
|
535
576
|
},
|
|
536
577
|
};
|
|
578
|
+
|
|
579
|
+
// Run plugins onRequestContext hook
|
|
580
|
+
if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
|
|
581
|
+
for (const plugin of dinouConfig.plugins) {
|
|
582
|
+
if (typeof plugin.onRequestContext === "function") {
|
|
583
|
+
try {
|
|
584
|
+
plugin.onRequestContext(req, res, context);
|
|
585
|
+
} catch (err) {
|
|
586
|
+
console.error(`[Dinou] Error running onRequestContext in plugin "${plugin.name || "unnamed"}":`, err);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
537
592
|
return context;
|
|
538
593
|
}
|
|
539
594
|
|
|
@@ -543,7 +598,7 @@ const clientManifestResolvedPath = path.resolve(
|
|
|
543
598
|
process.cwd(),
|
|
544
599
|
isWebpack
|
|
545
600
|
? `${outputFolder}/react-client-manifest.json`
|
|
546
|
-
:
|
|
601
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
547
602
|
);
|
|
548
603
|
|
|
549
604
|
function isManifestReady() {
|
|
@@ -583,7 +638,7 @@ if (!isDevelopment) {
|
|
|
583
638
|
process.cwd(),
|
|
584
639
|
isWebpack
|
|
585
640
|
? `${outputFolder}/react-client-manifest.json`
|
|
586
|
-
:
|
|
641
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
587
642
|
),
|
|
588
643
|
"utf8",
|
|
589
644
|
),
|
|
@@ -624,7 +679,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
624
679
|
if ((!isDevelopment && !dynamicState.value) || isStatic) {
|
|
625
680
|
let currentGeneratedAt = null;
|
|
626
681
|
try {
|
|
627
|
-
const metadataPath = path.join("dist2", reqPath, "metadata.json");
|
|
682
|
+
const metadataPath = path.join(".dinou/dist2", reqPath, "metadata.json");
|
|
628
683
|
if (existsSync(metadataPath)) {
|
|
629
684
|
const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
|
|
630
685
|
currentGeneratedAt = metaObj.generatedAt || null;
|
|
@@ -639,12 +694,12 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
639
694
|
req.query.buildId !== String(currentGeneratedAt));
|
|
640
695
|
|
|
641
696
|
const payloadPath = path.resolve(
|
|
642
|
-
"dist2",
|
|
697
|
+
".dinou/dist2",
|
|
643
698
|
reqPath.replace(/^\//, ""),
|
|
644
699
|
useOld ? "rsc._old.rsc" : "rsc.rsc",
|
|
645
700
|
);
|
|
646
701
|
|
|
647
|
-
const distDir = path.resolve("dist2");
|
|
702
|
+
const distDir = path.resolve(".dinou/dist2");
|
|
648
703
|
|
|
649
704
|
if (!payloadPath.startsWith(distDir)) {
|
|
650
705
|
return res.status(403).end();
|
|
@@ -748,7 +803,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
748
803
|
if (isDevelopment) {
|
|
749
804
|
isPathBlocked = true;
|
|
750
805
|
} else {
|
|
751
|
-
const htmlPath = path.join("dist2", reqPath, "index.html");
|
|
806
|
+
const htmlPath = path.join(".dinou/dist2", reqPath, "index.html");
|
|
752
807
|
if (!existsSync(htmlPath)) {
|
|
753
808
|
isPathBlocked = true;
|
|
754
809
|
}
|
|
@@ -784,7 +839,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
784
839
|
process.cwd(),
|
|
785
840
|
isWebpack
|
|
786
841
|
? `${outputFolder}/react-client-manifest.json`
|
|
787
|
-
:
|
|
842
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
788
843
|
),
|
|
789
844
|
"utf8",
|
|
790
845
|
),
|
|
@@ -819,7 +874,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
|
|
|
819
874
|
process.cwd(),
|
|
820
875
|
isWebpack
|
|
821
876
|
? `${outputFolder}/react-client-manifest.json`
|
|
822
|
-
:
|
|
877
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
823
878
|
),
|
|
824
879
|
"utf8",
|
|
825
880
|
),
|
|
@@ -875,7 +930,7 @@ app.post(/^\/____rsc_payload_error____\/.*\/?$/, async (req, res) => {
|
|
|
875
930
|
process.cwd(),
|
|
876
931
|
isWebpack
|
|
877
932
|
? `${outputFolder}/react-client-manifest.json`
|
|
878
|
-
:
|
|
933
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
879
934
|
),
|
|
880
935
|
"utf8",
|
|
881
936
|
),
|
|
@@ -990,7 +1045,7 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
990
1045
|
if (isDevelopment) {
|
|
991
1046
|
isPathBlocked = true;
|
|
992
1047
|
} else {
|
|
993
|
-
const htmlPath = path.join("dist2", req.path, "index.html");
|
|
1048
|
+
const htmlPath = path.join(".dinou/dist2", req.path, "index.html");
|
|
994
1049
|
if (!existsSync(htmlPath)) {
|
|
995
1050
|
isPathBlocked = true;
|
|
996
1051
|
}
|
|
@@ -1017,9 +1072,9 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
1017
1072
|
let htmlPathOld;
|
|
1018
1073
|
if (regenerating.has(reqPath)) {
|
|
1019
1074
|
// Still regenerating, serve old HTML if exists
|
|
1020
|
-
htmlPathOld = path.join("dist2", reqPath, "index._old.html");
|
|
1075
|
+
htmlPathOld = path.join(".dinou/dist2", reqPath, "index._old.html");
|
|
1021
1076
|
}
|
|
1022
|
-
const htmlPath = path.join("dist2", reqPath, "index.html");
|
|
1077
|
+
const htmlPath = path.join(".dinou/dist2", reqPath, "index.html");
|
|
1023
1078
|
// Decide which file to read
|
|
1024
1079
|
const fileToRead = htmlPathOld || htmlPath;
|
|
1025
1080
|
|
|
@@ -1037,7 +1092,7 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
1037
1092
|
let htmlContent = readFileSync(fileToRead, "utf8");
|
|
1038
1093
|
let buildId = "";
|
|
1039
1094
|
try {
|
|
1040
|
-
const metadataPath = path.join("dist2", reqPath, "metadata.json");
|
|
1095
|
+
const metadataPath = path.join(".dinou/dist2", reqPath, "metadata.json");
|
|
1041
1096
|
if (existsSync(metadataPath)) {
|
|
1042
1097
|
const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
|
|
1043
1098
|
buildId = metaObj.generatedAt || "";
|
|
@@ -1084,6 +1139,20 @@ app.get(/^\/.*\/?$/, async (req, res) => {
|
|
|
1084
1139
|
},
|
|
1085
1140
|
// Do not include res here
|
|
1086
1141
|
};
|
|
1142
|
+
|
|
1143
|
+
// Run plugins onRequestContext hook
|
|
1144
|
+
if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
|
|
1145
|
+
for (const plugin of dinouConfig.plugins) {
|
|
1146
|
+
if (typeof plugin.onRequestContext === "function") {
|
|
1147
|
+
try {
|
|
1148
|
+
plugin.onRequestContext(req, res, contextForChild);
|
|
1149
|
+
} catch (err) {
|
|
1150
|
+
console.error(`[Dinou] Error running onRequestContext in plugin "${plugin.name || "unnamed"}":`, err);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1087
1156
|
processLimiter
|
|
1088
1157
|
.run(async () => {
|
|
1089
1158
|
const isDynamic = true;
|
|
@@ -1211,7 +1280,12 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
1211
1280
|
const formData = new FormData();
|
|
1212
1281
|
|
|
1213
1282
|
for (const key in req.body) {
|
|
1214
|
-
if (
|
|
1283
|
+
if (
|
|
1284
|
+
key === "__dinou_func_id" ||
|
|
1285
|
+
key === "__dinou_args" ||
|
|
1286
|
+
key === "__dinou_formData_index"
|
|
1287
|
+
)
|
|
1288
|
+
continue;
|
|
1215
1289
|
formData.append(key, req.body[key]);
|
|
1216
1290
|
}
|
|
1217
1291
|
|
|
@@ -1222,15 +1296,22 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
1222
1296
|
}
|
|
1223
1297
|
}
|
|
1224
1298
|
|
|
1225
|
-
args = [formData];
|
|
1226
|
-
|
|
1227
1299
|
if (req.body.__dinou_args) {
|
|
1228
1300
|
try {
|
|
1229
|
-
const
|
|
1230
|
-
|
|
1301
|
+
const parsedArgs = JSON.parse(req.body.__dinou_args);
|
|
1302
|
+
if (req.body.__dinou_formData_index !== undefined) {
|
|
1303
|
+
const formDataIndex = parseInt(req.body.__dinou_formData_index, 10);
|
|
1304
|
+
parsedArgs[formDataIndex] = formData;
|
|
1305
|
+
args = parsedArgs;
|
|
1306
|
+
} else {
|
|
1307
|
+
args = [formData, ...parsedArgs];
|
|
1308
|
+
}
|
|
1231
1309
|
} catch (e) {
|
|
1232
|
-
console.error("Error parsing extra args in multipart request");
|
|
1310
|
+
console.error("Error parsing extra args in multipart request", e);
|
|
1311
|
+
args = [formData];
|
|
1233
1312
|
}
|
|
1313
|
+
} else {
|
|
1314
|
+
args = [formData];
|
|
1234
1315
|
}
|
|
1235
1316
|
} else {
|
|
1236
1317
|
id = req.body.id;
|
|
@@ -1382,7 +1463,7 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
1382
1463
|
process.cwd(),
|
|
1383
1464
|
isWebpack
|
|
1384
1465
|
? `${outputFolder}/react-client-manifest.json`
|
|
1385
|
-
:
|
|
1466
|
+
: `.dinou/react_client_manifest/react-client-manifest.json`,
|
|
1386
1467
|
);
|
|
1387
1468
|
// Verify that the manifest exists to avoid errors
|
|
1388
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": {
|