Updates
This commit is contained in:
parent
d75125d9fa
commit
070e6860d8
39
README.md
39
README.md
@ -67,18 +67,41 @@ The goal is a framework that is:
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Install Bunext directly from GitHub:
|
### From the Moduletrace registry (recommended)
|
||||||
|
|
||||||
|
Configure the `@moduletrace` scope to point at the registry — pick one:
|
||||||
|
|
||||||
|
**`.npmrc`** (works with npm, bun, and most tools):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
@moduletrace:registry=https://git.tben.me/api/packages/moduletrace/npm/
|
||||||
|
```
|
||||||
|
|
||||||
|
**`bunfig.toml`** (Bun-native):
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[install.scopes]
|
||||||
|
"@moduletrace" = { registry = "https://git.tben.me/api/packages/moduletrace/npm/" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Then install:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun add @moduletrace/bunext
|
||||||
|
```
|
||||||
|
|
||||||
|
Or globally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun add -g @moduletrace/bunext
|
||||||
|
```
|
||||||
|
|
||||||
|
### From GitHub (alternative)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bun add github:moduletrace/bunext
|
bun add github:moduletrace/bunext
|
||||||
```
|
```
|
||||||
|
|
||||||
Install globally:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bun add -g github:moduletrace/bunext
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
@ -157,7 +180,7 @@ bun run start
|
|||||||
**Global install** — install once and use `bunext` from anywhere:
|
**Global install** — install once and use `bunext` from anywhere:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bun add -g github:moduletrace/bunext
|
bun add -g @moduletrace/bunext
|
||||||
bunext dev
|
bunext dev
|
||||||
bunext build
|
bunext build
|
||||||
bunext start
|
bunext start
|
||||||
|
|||||||
2
dist/build/build.d.ts
vendored
2
dist/build/build.d.ts
vendored
@ -1,2 +0,0 @@
|
|||||||
#!/usr/bin/env bun
|
|
||||||
export {};
|
|
||||||
131
dist/build/build.js
vendored
131
dist/build/build.js
vendored
@ -1,131 +0,0 @@
|
|||||||
#!/usr/bin/env bun
|
|
||||||
import plugin from "bun-plugin-tailwind";
|
|
||||||
import { existsSync } from "fs";
|
|
||||||
import { rm } from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
||||||
console.log(`
|
|
||||||
🏗️ Bun Build Script
|
|
||||||
|
|
||||||
Usage: bun run build.ts [options]
|
|
||||||
|
|
||||||
Common Options:
|
|
||||||
--outdir <path> Output directory (default: "dist")
|
|
||||||
--minify Enable minification (or --minify.whitespace, --minify.syntax, etc)
|
|
||||||
--sourcemap <type> Sourcemap type: none|linked|inline|external
|
|
||||||
--target <target> Build target: browser|bun|node
|
|
||||||
--format <format> Output format: esm|cjs|iife
|
|
||||||
--splitting Enable code splitting
|
|
||||||
--packages <type> Package handling: bundle|external
|
|
||||||
--public-path <path> Public path for assets
|
|
||||||
--env <mode> Environment handling: inline|disable|prefix*
|
|
||||||
--conditions <list> Package.json export conditions (comma separated)
|
|
||||||
--external <list> External packages (comma separated)
|
|
||||||
--banner <text> Add banner text to output
|
|
||||||
--footer <text> Add footer text to output
|
|
||||||
--define <obj> Define global constants (e.g. --define.VERSION=1.0.0)
|
|
||||||
--help, -h Show this help message
|
|
||||||
|
|
||||||
Example:
|
|
||||||
bun run build.ts --outdir=dist --minify --sourcemap=linked --external=react,react-dom
|
|
||||||
`);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
const toCamelCase = (str) => str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
||||||
const parseValue = (value) => {
|
|
||||||
if (value === "true")
|
|
||||||
return true;
|
|
||||||
if (value === "false")
|
|
||||||
return false;
|
|
||||||
if (/^\d+$/.test(value))
|
|
||||||
return parseInt(value, 10);
|
|
||||||
if (/^\d*\.\d+$/.test(value))
|
|
||||||
return parseFloat(value);
|
|
||||||
if (value.includes(","))
|
|
||||||
return value.split(",").map((v) => v.trim());
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
function parseArgs() {
|
|
||||||
const config = {};
|
|
||||||
const args = process.argv.slice(2);
|
|
||||||
for (let i = 0; i < args.length; i++) {
|
|
||||||
const arg = args[i];
|
|
||||||
if (arg === undefined)
|
|
||||||
continue;
|
|
||||||
if (!arg.startsWith("--"))
|
|
||||||
continue;
|
|
||||||
if (arg.startsWith("--no-")) {
|
|
||||||
const key = toCamelCase(arg.slice(5));
|
|
||||||
config[key] = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!arg.includes("=") &&
|
|
||||||
(i === args.length - 1 || args[i + 1]?.startsWith("--"))) {
|
|
||||||
const key = toCamelCase(arg.slice(2));
|
|
||||||
config[key] = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let key;
|
|
||||||
let value;
|
|
||||||
if (arg.includes("=")) {
|
|
||||||
[key, value] = arg.slice(2).split("=", 2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
key = arg.slice(2);
|
|
||||||
value = args[++i] ?? "";
|
|
||||||
}
|
|
||||||
key = toCamelCase(key);
|
|
||||||
if (key.includes(".")) {
|
|
||||||
const [parentKey, childKey] = key.split(".");
|
|
||||||
config[parentKey] = config[parentKey] || {};
|
|
||||||
config[parentKey][childKey] = parseValue(value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
config[key] = parseValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
const formatFileSize = (bytes) => {
|
|
||||||
const units = ["B", "KB", "MB", "GB"];
|
|
||||||
let size = bytes;
|
|
||||||
let unitIndex = 0;
|
|
||||||
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
||||||
size /= 1024;
|
|
||||||
unitIndex++;
|
|
||||||
}
|
|
||||||
return `${size.toFixed(2)} ${units[unitIndex]}`;
|
|
||||||
};
|
|
||||||
console.log("\n🚀 Starting build process...\n");
|
|
||||||
const cliConfig = parseArgs();
|
|
||||||
const outdir = cliConfig.outdir || path.join(process.cwd(), "dist");
|
|
||||||
if (existsSync(outdir)) {
|
|
||||||
console.log(`🗑️ Cleaning previous build at ${outdir}`);
|
|
||||||
await rm(outdir, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
const start = performance.now();
|
|
||||||
const entrypoints = [...new Bun.Glob("**.html").scanSync("src/app")]
|
|
||||||
.map((a) => path.resolve("src/app", a))
|
|
||||||
.filter((dir) => !dir.includes("node_modules"));
|
|
||||||
console.log(`📄 Found ${entrypoints.length} HTML ${entrypoints.length === 1 ? "file" : "files"} to process\n`);
|
|
||||||
const result = await Bun.build({
|
|
||||||
entrypoints,
|
|
||||||
outdir,
|
|
||||||
plugins: [plugin],
|
|
||||||
minify: true,
|
|
||||||
target: "browser",
|
|
||||||
sourcemap: "linked",
|
|
||||||
define: {
|
|
||||||
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
||||||
},
|
|
||||||
...cliConfig,
|
|
||||||
});
|
|
||||||
const end = performance.now();
|
|
||||||
const outputTable = result.outputs.map((output) => ({
|
|
||||||
File: path.relative(process.cwd(), output.path),
|
|
||||||
Type: output.kind,
|
|
||||||
Size: formatFileSize(output.size),
|
|
||||||
}));
|
|
||||||
console.table(outputTable);
|
|
||||||
const buildTime = (end - start).toFixed(2);
|
|
||||||
console.log(`\n✅ Build completed in ${buildTime}ms\n`);
|
|
||||||
5
dist/functions/server/handle-hmr-update.d.ts
vendored
5
dist/functions/server/handle-hmr-update.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
type Params = {
|
|
||||||
req: Request;
|
|
||||||
};
|
|
||||||
export default function ({ req }: Params): Promise<Response>;
|
|
||||||
export {};
|
|
||||||
54
dist/functions/server/handle-hmr-update.js
vendored
54
dist/functions/server/handle-hmr-update.js
vendored
@ -1,54 +0,0 @@
|
|||||||
import grabDirNames from "../../utils/grab-dir-names";
|
|
||||||
import { AppData } from "../../data/app-data";
|
|
||||||
import path from "path";
|
|
||||||
import grabRootFile from "./web-pages/grab-root-file";
|
|
||||||
import grabPageBundledReactComponent from "./web-pages/grab-page-bundled-react-component";
|
|
||||||
import writeHMRTsxModule from "./web-pages/write-hmr-tsx-module";
|
|
||||||
const { BUNX_HYDRATION_SRC_DIR } = grabDirNames();
|
|
||||||
export default async function ({ req }) {
|
|
||||||
try {
|
|
||||||
const url = new URL(req.url);
|
|
||||||
const target_href = url.searchParams.get("href");
|
|
||||||
if (!target_href) {
|
|
||||||
return new Response(`No HREF passed to /${AppData["ClientHMRPath"]}`, { status: 404 });
|
|
||||||
}
|
|
||||||
const target_href_url = new URL(target_href);
|
|
||||||
const match = global.ROUTER.match(target_href_url.pathname);
|
|
||||||
if (!match?.filePath) {
|
|
||||||
return new Response(`No pages file matched for this path`, {
|
|
||||||
status: 404,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const out_file = path.join(BUNX_HYDRATION_SRC_DIR, target_href_url.pathname, "index.js");
|
|
||||||
const { root_file } = grabRootFile();
|
|
||||||
const { tsx } = (await grabPageBundledReactComponent({
|
|
||||||
file_path: match.filePath,
|
|
||||||
root_file,
|
|
||||||
})) || {};
|
|
||||||
if (!tsx) {
|
|
||||||
throw new Error(`Couldn't grab txt string`);
|
|
||||||
}
|
|
||||||
const artifact = await writeHMRTsxModule({
|
|
||||||
tsx,
|
|
||||||
out_file,
|
|
||||||
});
|
|
||||||
const file = Bun.file(out_file);
|
|
||||||
if (await file.exists()) {
|
|
||||||
return new Response(file, {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "text/javascript",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return new Response("Not found", {
|
|
||||||
status: 404,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
const error_msg = error.message;
|
|
||||||
console.error(error_msg);
|
|
||||||
return new Response(error_msg || "HMR Error", {
|
|
||||||
status: 404,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
0
dist/index.js
vendored
Executable file → Normal file
0
dist/index.js
vendored
Executable file → Normal file
@ -2,7 +2,7 @@
|
|||||||
"name": "@moduletrace/bunext",
|
"name": "@moduletrace/bunext",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
@ -28,7 +28,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsc --watch",
|
"dev": "tsc --watch",
|
||||||
"git:push": "tsc --noEmit && tsc && git add . && git commit -m 'Update bundler. Handle non-existent file error.' && git push",
|
"git:push": "tsc --noEmit && tsc && git add . && git commit -m 'Update bundler. Handle non-existent file error.' && git push",
|
||||||
"compile": "bun build ./src/commands/index.ts --compile --outfile bin/bunext",
|
"compile": "bun build ./src/commands/index.ts --compile --outfile bin/bunext --minify",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"test": "bun test --max-concurrency=1"
|
"test": "bun test --max-concurrency=1"
|
||||||
},
|
},
|
||||||
@ -54,7 +54,6 @@
|
|||||||
"registry": "https://npm.pkg.github.com"
|
"registry": "https://npm.pkg.github.com"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@moduletrace/bunext": "github:moduletrace/bunext",
|
|
||||||
"@tailwindcss/postcss": "^4.2.2",
|
"@tailwindcss/postcss": "^4.2.2",
|
||||||
"bun-plugin-tailwind": "^0.1.2",
|
"bun-plugin-tailwind": "^0.1.2",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^5.6.2",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user