From 3f18e881fa1a843f22bd15efc3c457e0e56ec21a Mon Sep 17 00:00:00 2001 From: EthanShoeDev <13422990+EthanShoeDev@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:52:35 -0500 Subject: [PATCH] dynamic config --- bun.lock | 5 +- docs/bun-bundler.md | 1814 ++++++++++++++++++ packages/dsc-ts/package.json | 14 + packages/dsc-ts/src/bin.ts | 76 +- packages/dsc-ts/src/dsl.ts | 54 - packages/dsc-ts/src/dsl/dsl-core.ts | 48 + packages/dsc-ts/src/dsl/dsl-interface.ts | 84 + packages/dsc-ts/src/index.ts | 1 + packages/dsc-ts/src/{ => utils}/dsc-utils.ts | 8 +- packages/dsc-ts/src/{ => utils}/utils.ts | 0 packages/dsc-ts/tsconfig.json | 13 + packages/example-config/tsconfig.json | 5 + packages/example-config/winos-config.ts | 40 +- turbo.jsonc | 4 + 14 files changed, 2077 insertions(+), 89 deletions(-) create mode 100644 docs/bun-bundler.md delete mode 100644 packages/dsc-ts/src/dsl.ts create mode 100644 packages/dsc-ts/src/dsl/dsl-core.ts create mode 100644 packages/dsc-ts/src/dsl/dsl-interface.ts create mode 100644 packages/dsc-ts/src/index.ts rename packages/dsc-ts/src/{ => utils}/dsc-utils.ts (93%) rename packages/dsc-ts/src/{ => utils}/utils.ts (100%) create mode 100644 packages/dsc-ts/tsconfig.json create mode 100644 packages/example-config/tsconfig.json diff --git a/bun.lock b/bun.lock index 8e18c26..359045b 100644 --- a/bun.lock +++ b/bun.lock @@ -36,10 +36,7 @@ "name": "example-config", "version": "0.0.1", "dependencies": { - "@effect/cli": "catalog:", - "@effect/platform": "catalog:", - "@effect/platform-bun": "catalog:", - "effect": "catalog:", + "dsc-ts": "workspace:*", }, "devDependencies": { "typescript": "catalog:", diff --git a/docs/bun-bundler.md b/docs/bun-bundler.md new file mode 100644 index 0000000..e681381 --- /dev/null +++ b/docs/bun-bundler.md @@ -0,0 +1,1814 @@ +# Bundler + +> Bun's fast native bundler for JavaScript, TypeScript, JSX, and more + +export const name_0 = undefined + +Bun's fast native bundler can be used via the `bun build` CLI command or the `Bun.build()` JavaScript API. + +### At a Glance + +* JS API: `await Bun.build({ entrypoints, outdir })` +* CLI: `bun build --outdir ./out` +* Watch: `--watch` for incremental rebuilds +* Targets: `--target browser|bun|node` +* Formats: `--format esm|cjs|iife` (experimental for cjs/iife) + + + + ```ts title="build.ts" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + await Bun.build({ + entrypoints: ['./index.tsx'], + outdir: './build', + }); + ``` + + + + ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} + bun build ./index.tsx --outdir ./build + ``` + + + +It's fast. The numbers below represent performance on esbuild's [three.js benchmark](https://github.com/oven-sh/bun/tree/main/bench/bundle). + + + + + +## Why bundle? + +The bundler is a key piece of infrastructure in the JavaScript ecosystem. As a brief overview of why bundling is so important: + +* **Reducing HTTP requests.** A single package in `node_modules` may consist of hundreds of files, and large applications may have dozens of such dependencies. Loading each of these files with a separate HTTP request becomes untenable very quickly, so bundlers are used to convert our application source code into a smaller number of self-contained "bundles" that can be loaded with a single request. +* **Code transforms.** Modern apps are commonly built with languages or tools like TypeScript, JSX, and CSS modules, all of which must be converted into plain JavaScript and CSS before they can be consumed by a browser. The bundler is the natural place to configure these transformations. +* **Framework features.** Frameworks rely on bundler plugins & code transformations to implement common patterns like file-system routing, client-server code co-location (think `getServerSideProps` or Remix loaders), and server components. +* **Full-stack Applications.** Bun's bundler can handle both server and client code in a single command, enabling optimized production builds and single-file executables. With build-time HTML imports, you can bundle your entire application — frontend assets and backend server — into a single deployable unit. + +Let's jump into the bundler API. + +The Bun bundler is not intended to replace `tsc` for typechecking or generating type declarations. + +## Basic example + +Let's build our first bundle. You have the following two files, which implement a simple client-side rendered React app. + + + ```tsx index.tsx icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + import * as ReactDOM from "react-dom/client"; + import { Component } from "./Component"; + + const root = ReactDOM.createRoot(document.getElementById("root")!); + root.render(); + ``` + + ```tsx Component.tsx icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + export function Component(props: { message: string }) { + return

{props.message}

; + } + ``` +
+ +Here, `index.tsx` is the "entrypoint" to our application. Commonly, this will be a script that performs some side effect, like starting a server or—in this case—initializing a React root. Because we're using TypeScript & JSX, we need to bundle our code before it can be sent to the browser. + +To create our bundle: + + + ```ts build.ts icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + await Bun.build({ + entrypoints: ["./index.tsx"], + outdir: "./out", + }); + ``` + + ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} + bun build ./index.tsx --outdir ./out + ``` + + +For each file specified in `entrypoints`, Bun will generate a new bundle. This bundle will be written to disk in the `./out` directory (as resolved from the current working directory). After running the build, the file system looks like this: + +```text title="file system" icon="folder-tree" theme={"theme":{"light":"github-light","dark":"dracula"}} +. +├── index.tsx +├── Component.tsx +└── out + └── index.js +``` + +The contents of `out/index.js` will look something like this: + +```js title="out/index.js" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/javascript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=81efd0ad0d779debfa163bfd906ef6a6" theme={"theme":{"light":"github-light","dark":"dracula"}} +// out/index.js +// ... +// ~20k lines of code +// including the contents of `react-dom/client` and all its dependencies +// this is where the $jsxDEV and $createRoot functions are defined + +// Component.tsx +function Component(props) { + return $jsxDEV( + "p", + { + children: props.message, + }, + undefined, + false, + undefined, + this, + ); +} + +// index.tsx +var rootNode = document.getElementById("root"); +var root = $createRoot(rootNode); +root.render( + $jsxDEV( + Component, + { + message: "Sup!", + }, + undefined, + false, + undefined, + this, + ), +); +``` + +## Watch mode + +Like the runtime and test runner, the bundler supports watch mode natively. + +```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} +bun build ./index.tsx --outdir ./out --watch +``` + +## Content types + +Like the Bun runtime, the bundler supports an array of file types out of the box. The following table breaks down the bundler's set of standard "loaders". Refer to [Bundler > File types](/bundler/loaders) for full documentation. + +| Extensions | Details | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `.js` `.jsx` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` | Uses Bun's built-in transpiler to parse the file and transpile TypeScript/JSX syntax to vanilla JavaScript. The bundler executes a set of default transforms including dead code elimination and tree shaking. At the moment Bun does not attempt to down-convert syntax; if you use recently ECMAScript syntax, that will be reflected in the bundled code. | +| `.json` | JSON files are parsed and inlined into the bundle as a JavaScript object.

`js
import pkg from "./package.json";
pkg.name; // => "my-package"
` | +| `.jsonc` | JSON with comments. Files are parsed and inlined into the bundle as a JavaScript object.

`js
import config from "./config.jsonc";
config.name; // => "my-config"
` | +| `.toml` | TOML files are parsed and inlined into the bundle as a JavaScript object.

`js
import config from "./bunfig.toml";
config.logLevel; // => "debug"
` | +| `.yaml` `.yml` | YAML files are parsed and inlined into the bundle as a JavaScript object.

`js
import config from "./config.yaml";
config.name; // => "my-app"
` | +| `.txt` | The contents of the text file are read and inlined into the bundle as a string.

`js
import contents from "./file.txt";
console.log(contents); // => "Hello, world!"
` | +| `.html` | HTML files are processed and any referenced assets (scripts, stylesheets, images) are bundled. | +| `.css` | CSS files are bundled together into a single `.css` file in the output directory. | +| `.node` `.wasm` | These files are supported by the Bun runtime, but during bundling they are treated as assets. | + +### Assets + +If the bundler encounters an import with an unrecognized extension, it treats the imported file as an external file. The referenced file is copied as-is into `outdir`, and the import is resolved as a path to the file. + + + ```ts Input icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + // bundle entrypoint + import logo from "./logo.svg"; + console.log(logo); + ``` + + ```ts Output icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/javascript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=81efd0ad0d779debfa163bfd906ef6a6" theme={"theme":{"light":"github-light","dark":"dracula"}} + // bundled output + var logo = "./logo-a7305bdef.svg"; + console.log(logo); + ``` + + +The exact behavior of the file loader is also impacted by [`naming`](#naming) and [`publicPath`](#publicpath). + +Refer to the [Bundler > Loaders](/bundler/loaders) page for more complete documentation on the file loader. + +### Plugins + +The behavior described in this table can be overridden or extended with plugins. Refer to the [Bundler > Loaders](/bundler/loaders) page for complete documentation. + +## API + +### entrypoints + +Required + +An array of paths corresponding to the entrypoints of our application. One bundle will be generated for each entrypoint. + + + + ```ts title="build.ts" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + const result = await Bun.build({ + entrypoints: ["./index.ts"], + }); + // => { success: boolean, outputs: BuildArtifact[], logs: BuildMessage[] } + ``` + + + + ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} + bun build ./index.ts + ``` + + + +### outdir + +The directory where output files will be written. + + + + ```ts title="build.ts" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + const result = await Bun.build({ + entrypoints: ['./index.ts'], + outdir: './out' + }); + // => { success: boolean, outputs: BuildArtifact[], logs: BuildMessage[] } + ``` + + + + ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} + bun build ./index.ts --outdir ./out + ``` + + + +If `outdir` is not passed to the JavaScript API, bundled code will not be written to disk. Bundled files are returned in an array of `BuildArtifact` objects. These objects are Blobs with extra properties; see [Outputs](#outputs) for complete documentation. + +```ts title="build.ts" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} +const result = await Bun.build({ + entrypoints: ["./index.ts"], +}); + +for (const res of result.outputs) { + // Can be consumed as blobs + await res.text(); + + // Bun will set Content-Type and Etag headers + new Response(res); + + // Can be written manually, but you should use `outdir` in this case. + Bun.write(path.join("out", res.path), res); +} +``` + +When `outdir` is set, the `path` property on a `BuildArtifact` will be the absolute path to where it was written to. + +### target + +The intended execution environment for the bundle. + + + + ```ts title="build.ts" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + await Bun.build({ + entrypoints: ['./index.ts'], + outdir: './out', + target: 'browser', // default + }) + ``` + + + + ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} + bun build ./index.ts --outdir ./out --target browser + ``` + + + +Depending on the target, Bun will apply different module resolution rules and optimizations. + + + **Default.** For generating bundles that are intended for execution by a browser. Prioritizes the `"browser"` export + condition when resolving imports. Importing any built-in modules, like `node:events` or `node:path` will work, but + calling some functions, like `fs.readFile` will not work. + + + + For generating bundles that are intended to be run by the Bun runtime. In many cases, it isn't necessary to bundle server-side code; you can directly execute the source code without modification. However, bundling your server code can reduce startup times and improve running performance. This is the target to use for building full-stack applications with build-time HTML imports, where both server and client code are bundled together. + + All bundles generated with `target: "bun"` are marked with a special `// @bun` pragma, which indicates to the Bun runtime that there's no need to re-transpile the file before execution. + + If any entrypoints contains a Bun shebang (`#!/usr/bin/env bun`) the bundler will default to `target: "bun"` instead of `"browser"`. + + When using `target: "bun"` and `format: "cjs"` together, the `// @bun @bun-cjs` pragma is added and the CommonJS wrapper function is not compatible with Node.js. + + + + For generating bundles that are intended to be run by Node.js. Prioritizes the `"node"` export condition when + resolving imports, and outputs `.mjs`. In the future, this will automatically polyfill the Bun global and other + built-in `bun:*` modules, though this is not yet implemented. + + +### format + +Specifies the module format to be used in the generated bundles. + +Bun defaults to `"esm"`, and provides experimental support for `"cjs"` and `"iife"`. + +#### format: "esm" - ES Module + +This is the default format, which supports ES Module syntax including top-level await, `import.meta`, and more. + + + + ```ts title="build.ts" icon="https://mintcdn.com/bun-1dd33a4e/Hq64iapoQXHbYMEN/icons/typescript.svg?fit=max&auto=format&n=Hq64iapoQXHbYMEN&q=85&s=c6cceedec8f82d2cc803d7c6ec82b240" theme={"theme":{"light":"github-light","dark":"dracula"}} + await Bun.build({ + entrypoints: ['./index.tsx'], + outdir: './out', + format: "esm", + }) + ``` + + + + ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}} + bun build ./index.tsx --outdir ./out --format esm + ``` + + + +To use ES Module syntax in browsers, set `format` to `"esm"` and make sure your `