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
|
||||
|
||||
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
|
||||
bun add github:moduletrace/bunext
|
||||
```
|
||||
|
||||
Install globally:
|
||||
|
||||
```bash
|
||||
bun add -g github:moduletrace/bunext
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
@ -157,7 +180,7 @@ bun run start
|
||||
**Global install** — install once and use `bunext` from anywhere:
|
||||
|
||||
```bash
|
||||
bun add -g github:moduletrace/bunext
|
||||
bun add -g @moduletrace/bunext
|
||||
bunext dev
|
||||
bunext build
|
||||
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",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
@ -28,7 +28,7 @@
|
||||
"scripts": {
|
||||
"dev": "tsc --watch",
|
||||
"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",
|
||||
"test": "bun test --max-concurrency=1"
|
||||
},
|
||||
@ -54,7 +54,6 @@
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"dependencies": {
|
||||
"@moduletrace/bunext": "github:moduletrace/bunext",
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"bun-plugin-tailwind": "^0.1.2",
|
||||
"chalk": "^5.6.2",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user