@ramonyx/bundler 0.4.1 → 0.4.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/README.md +12 -5
- package/dist/edge.d.ts +16 -0
- package/dist/edge.js +13 -1
- package/dist/edge.js.map +1 -1
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
# @ramonyx/bundler
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build pipeline for Ramonyx: Vite client bundles, edge builds, static prerender, and plugin hooks.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
> runtime Rust/V8 bersifat eksperimental. Butuh **Node.js ≥ 24**.
|
|
5
|
+
Part of the Ramonyx framework. Requires Node.js 24 or newer and ESM.
|
|
7
6
|
|
|
8
|
-
##
|
|
7
|
+
## Install
|
|
9
8
|
|
|
10
9
|
```bash
|
|
11
10
|
npm install @ramonyx/bundler
|
|
12
11
|
```
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
## Documentation
|
|
14
|
+
|
|
15
|
+
- [Ramonyx docs](https://ramonyx.devmoon.net/docs/getting-started)
|
|
16
|
+
- [Repository](https://github.com/RamonyxJS/ramonyx)
|
|
17
|
+
- [Issues](https://github.com/RamonyxJS/ramonyx/issues)
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT
|
package/dist/edge.d.ts
CHANGED
|
@@ -5,8 +5,24 @@ export interface BuildEdgeOptions {
|
|
|
5
5
|
readonly outDir?: string;
|
|
6
6
|
/** URL bundle klien (default: manifest `dist/client`, fallback `/assets/client.js`). */
|
|
7
7
|
readonly clientScript?: string;
|
|
8
|
+
/** Strategi muat bundle klien (default eager). */
|
|
9
|
+
readonly clientLoad?: "eager" | "interaction";
|
|
10
|
+
/** Skrip bootstrap inline (nonce) sebelum hydration. */
|
|
11
|
+
readonly clientBootstrap?: string;
|
|
8
12
|
/** Aktifkan SSR streaming di artefak; default true (renderer React mendukung). */
|
|
9
13
|
readonly streaming?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Batasi halaman yang ikut artefak (mis. `["/"]` untuk landing-only Worker).
|
|
16
|
+
* Default: semua halaman.
|
|
17
|
+
*/
|
|
18
|
+
readonly pagePaths?: readonly string[];
|
|
19
|
+
/** Batasi route API yang ikut artefak; default semua. */
|
|
20
|
+
readonly apiPaths?: readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* Modul dokumen kustom relatif terhadap `appDir` (mengekspor `document` —
|
|
23
|
+
* `DocumentRenderer`). Tanpa ini artefak memakai dokumen default.
|
|
24
|
+
*/
|
|
25
|
+
readonly document?: string;
|
|
10
26
|
readonly minify?: boolean;
|
|
11
27
|
/** Plugin Vite tambahan (harus edge-safe — ADR-0067). */
|
|
12
28
|
readonly plugins?: readonly PluginOption[];
|
package/dist/edge.js
CHANGED
|
@@ -28,10 +28,19 @@ export async function buildEdge(options) {
|
|
|
28
28
|
const outDir = resolve(appDir, options.outDir ?? "dist/edge");
|
|
29
29
|
const entryDir = join(appDir, ".ramonyx");
|
|
30
30
|
const entryFile = join(entryDir, "edge-entry.ts");
|
|
31
|
-
const [
|
|
31
|
+
const [allPages, allApiRoutes] = await Promise.all([
|
|
32
32
|
loadPageRoutes({ dir: routesDir }),
|
|
33
33
|
listApiRoutes({ dir: routesDir }),
|
|
34
34
|
]);
|
|
35
|
+
const pages = options.pagePaths === undefined
|
|
36
|
+
? allPages
|
|
37
|
+
: allPages.filter((page) => options.pagePaths?.includes(page.path) === true);
|
|
38
|
+
const apiRoutes = options.apiPaths === undefined
|
|
39
|
+
? allApiRoutes
|
|
40
|
+
: allApiRoutes.filter((route) => options.apiPaths?.includes(route.routePath) === true);
|
|
41
|
+
if (pages.length === 0) {
|
|
42
|
+
throw new Error("buildEdge: tidak ada halaman yang cocok dengan pagePaths");
|
|
43
|
+
}
|
|
35
44
|
const middlewareCandidate = join(routesDir, "middleware.ts");
|
|
36
45
|
const middlewareFile = existsSync(middlewareCandidate) ? middlewareCandidate : undefined;
|
|
37
46
|
const clientDir = join(appDir, "dist/client");
|
|
@@ -45,7 +54,10 @@ export async function buildEdge(options) {
|
|
|
45
54
|
pages,
|
|
46
55
|
apiRoutes,
|
|
47
56
|
middlewareFile,
|
|
57
|
+
document: options.document === undefined ? undefined : resolve(appDir, options.document),
|
|
48
58
|
clientScript,
|
|
59
|
+
clientLoad: options.clientLoad,
|
|
60
|
+
clientBootstrap: options.clientBootstrap,
|
|
49
61
|
streaming: options.streaming ?? true,
|
|
50
62
|
assets,
|
|
51
63
|
}));
|
package/dist/edge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge.js","sourceRoot":"","sources":["../../../packages/bundler/src/edge.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAElF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAqB,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"edge.js","sourceRoot":"","sources":["../../../packages/bundler/src/edge.ts"],"names":[],"mappings":"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","sourcesContent":["// Build target edge/serverless (ADR-0058): bundel SSR satu berkas dari entry yang digenerate\n// (impor statis, tanpa `node:fs`) + guard agar tidak ada API Node yang lolos.\n//\n// Hasil: `<outDir>/index.js` — ESM dengan `export default { fetch(request) }`,\n// kontrak Cloudflare Workers / Vercel Edge / Deno Deploy / runtime fetch standar.\n\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { generateServerEntry, listApiRoutes, loadPageRoutes } from \"@ramonyx/compiler\";\nimport { errorHint } from \"@ramonyx/core\";\nimport { build, type PluginOption } from \"vite\";\nimport { assetInfoMap } from \"./assets.ts\";\nimport { readClientScript } from \"./build.ts\";\nimport { readAssetManifest } from \"./manifest.ts\";\n\nexport interface BuildEdgeOptions {\n readonly appDir: string;\n /** Relatif terhadap appDir; default \"dist/edge\". */\n readonly outDir?: string;\n /** URL bundle klien (default: manifest `dist/client`, fallback `/assets/client.js`). */\n readonly clientScript?: string;\n /** Strategi muat bundle klien (default eager). */\n readonly clientLoad?: \"eager\" | \"interaction\";\n /** Skrip bootstrap inline (nonce) sebelum hydration. */\n readonly clientBootstrap?: string;\n /** Aktifkan SSR streaming di artefak; default true (renderer React mendukung). */\n readonly streaming?: boolean;\n /**\n * Batasi halaman yang ikut artefak (mis. `[\"/\"]` untuk landing-only Worker).\n * Default: semua halaman.\n */\n readonly pagePaths?: readonly string[];\n /** Batasi route API yang ikut artefak; default semua. */\n readonly apiPaths?: readonly string[];\n /**\n * Modul dokumen kustom relatif terhadap `appDir` (mengekspor `document` —\n * `DocumentRenderer`). Tanpa ini artefak memakai dokumen default.\n */\n readonly document?: string;\n readonly minify?: boolean;\n /** Plugin Vite tambahan (harus edge-safe — ADR-0067). */\n readonly plugins?: readonly PluginOption[];\n}\n\nexport interface BuildEdgeResult {\n readonly outDir: string;\n readonly entryFile: string;\n readonly outputFile: string;\n readonly bytes: number;\n}\n\nconst NODE_IMPORT = /[\"'](node:[a-z0-9_/-]+)[\"']/g;\n\n/**\n * Membangun artefak edge dari aplikasi Ramonyx.\n *\n * Manifest rute dibangun saat build (impor statis hasil codegen) sehingga artefak tidak\n * menyentuh filesystem saat runtime; seluruh dependency dibundel (`ssr.noExternal`),\n * `process.env.NODE_ENV` di-define sebagai `\"production\"`, dan hasilnya diperiksa:\n * impor `node:*` yang lolos = error (runtime edge tidak menyediakannya).\n */\nexport async function buildEdge(options: BuildEdgeOptions): Promise<BuildEdgeResult> {\n // Path absolut: entry Vite diresolusi relatif terhadap `root`, path relatif akan tergandakan.\n const appDir = resolve(options.appDir);\n const routesDir = join(appDir, \"src/routes\");\n const outDir = resolve(appDir, options.outDir ?? \"dist/edge\");\n const entryDir = join(appDir, \".ramonyx\");\n const entryFile = join(entryDir, \"edge-entry.ts\");\n\n const [allPages, allApiRoutes] = await Promise.all([\n loadPageRoutes({ dir: routesDir }),\n listApiRoutes({ dir: routesDir }),\n ]);\n const pages =\n options.pagePaths === undefined\n ? allPages\n : allPages.filter((page) => options.pagePaths?.includes(page.path) === true);\n const apiRoutes =\n options.apiPaths === undefined\n ? allApiRoutes\n : allApiRoutes.filter((route) => options.apiPaths?.includes(route.routePath) === true);\n if (pages.length === 0) {\n throw new Error(\"buildEdge: tidak ada halaman yang cocok dengan pagePaths\");\n }\n\n const middlewareCandidate = join(routesDir, \"middleware.ts\");\n const middlewareFile = existsSync(middlewareCandidate) ? middlewareCandidate : undefined;\n const clientDir = join(appDir, \"dist/client\");\n const clientScript = options.clientScript ?? (await readClientScript(clientDir));\n\n // Peta aset di-inline (artefak edge tanpa fs — ADR-0069): URL + dimensi + varian (ADR-0079).\n const manifest = await readAssetManifest(clientDir);\n const assets = assetInfoMap(manifest);\n\n await mkdir(entryDir, { recursive: true });\n await writeFile(\n entryFile,\n generateServerEntry({\n from: entryDir,\n pages,\n apiRoutes,\n middlewareFile,\n document: options.document === undefined ? undefined : resolve(appDir, options.document),\n clientScript,\n clientLoad: options.clientLoad,\n clientBootstrap: options.clientBootstrap,\n streaming: options.streaming ?? true,\n assets,\n }),\n );\n\n await build({\n configFile: false,\n root: appDir,\n logLevel: \"warn\",\n esbuild: { jsx: \"automatic\" },\n plugins: [...(options.plugins ?? [])],\n // `*.server.ts` tetap nyata di edge (server) — plugin stub hanya untuk bundle klien.\n // Runtime edge tidak punya `process` — define agar React memakai build produksi.\n define: { \"process.env.NODE_ENV\": JSON.stringify(\"production\") },\n ssr: { noExternal: true },\n build: {\n outDir,\n emptyOutDir: true,\n target: \"es2022\",\n minify: options.minify ?? true,\n ssr: entryFile,\n rollupOptions: {\n output: { entryFileNames: \"index.js\", format: \"esm\", codeSplitting: false },\n },\n },\n });\n\n const outputFile = join(outDir, \"index.js\");\n const bundle = await readFile(outputFile, \"utf8\");\n const nodeImports = [\n ...new Set([...bundle.matchAll(NODE_IMPORT)].map((match) => match[1] ?? \"\")),\n ];\n if (nodeImports.length > 0) {\n throw new Error(\n `bundel edge memuat API Node (${nodeImports.join(\", \")}) — periksa middleware/kode aplikasi ` +\n `yang memakai \\`node:*\\` (mis. \\`guardedFetch\\` dari @ramonyx/security/ssrf). ${errorHint(\"RMX-EDGE-1\")}`,\n );\n }\n\n const info = await stat(outputFile);\n return { outDir, entryFile, outputFile, bytes: info.size };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramonyx/bundler",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Build pipeline for Ramonyx: Vite client bundles, edge builds, static prerender, and plugin hooks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"node": ">=24"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ramonyx/compiler": "^0.4.
|
|
23
|
-
"@ramonyx/core": "^0.4.
|
|
22
|
+
"@ramonyx/compiler": "^0.4.2",
|
|
23
|
+
"@ramonyx/core": "^0.4.2",
|
|
24
24
|
"vite": "8.3.4"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
@@ -29,5 +29,9 @@
|
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "https://github.com/RamonyxJS/ramonyx"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://ramonyx.devmoon.net/",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/RamonyxJS/ramonyx/issues"
|
|
32
36
|
}
|
|
33
37
|
}
|