From 629317b6420e755c0eccffe97ff535fe28644460 Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Tue, 4 Apr 2023 20:22:59 -0700 Subject: [PATCH] Add multistage build proposal --- docs/rfcs/README.md | 6 +-- docs/rfcs/bun-bundler.ts | 24 +++++----- docs/rfcs/bun-multistage-build.ts | 78 +++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 docs/rfcs/bun-multistage-build.ts diff --git a/docs/rfcs/README.md b/docs/rfcs/README.md index ffa91d8e05..db344af11c 100644 --- a/docs/rfcs/README.md +++ b/docs/rfcs/README.md @@ -1,5 +1,5 @@ # RFCs -| Number | Name | Issue | -| ------ | ----------------- | ---------------------------- | -| 1 | `Bun.Bundler` API | (Proposal)[./bun-bundler.ts] | +| Number | Name | Issue | +| ------ | ----------------- | --------------------------------- | +| 1 | `Bun.Bundler` API | (`Bun.Bundler`)[./bun-bundler.ts] | diff --git a/docs/rfcs/bun-bundler.ts b/docs/rfcs/bun-bundler.ts index c0c5739f37..22c731e228 100644 --- a/docs/rfcs/bun-bundler.ts +++ b/docs/rfcs/bun-bundler.ts @@ -125,15 +125,17 @@ interface BuildOptions extends BundlerOptions { entrypoints: string[]; rootDir?: string; // equiv. outbase - naming?: { - /** Documentation: https://esbuild.github.io/api/#entry-names */ - entry?: string; - /** Documentation: https://esbuild.github.io/api/#chunk-names */ - chunk?: string; - /** Documentation: https://esbuild.github.io/api/#asset-names */ - asset?: string; - extensions?: { [ext: string]: string }; - }; + naming?: + | string + | { + /** Documentation: https://esbuild.github.io/api/#entry-names */ + entry?: string; + /** Documentation: https://esbuild.github.io/api/#chunk-names */ + chunk?: string; + /** Documentation: https://esbuild.github.io/api/#asset-names */ + asset?: string; + extensions?: { [ext: string]: string }; + }; /** Documentation: https://esbuild.github.io/api/#external */ external?: { @@ -210,12 +212,12 @@ type BuildResult = { }; type LazyBuildResult = { - then(cb: (result: LazyBuildResult) => BuildOptions): LazyBuildResult; + then(cb: (context: any) => BuildOptions): LazyBuildResult; run(): Promise>; write(dir: string): Promise>; }; -declare class Bundler { +export declare class Bundler { constructor(options: BundlerOptions); makeBuild: (options: BuildOptions) => LazyBuildResult; handle: ( diff --git a/docs/rfcs/bun-multistage-build.ts b/docs/rfcs/bun-multistage-build.ts new file mode 100644 index 0000000000..f308db7ba9 --- /dev/null +++ b/docs/rfcs/bun-multistage-build.ts @@ -0,0 +1,78 @@ +import { Bundler } from "./bun-bundler"; + +const bundler = new Bundler({ + // ... +}); + +const router = new Bun.FileSystemRouter({ + dir: "./app", + style: "nextjs", +}); + +const multistageBuild = bundler + .makeBuild({ + // server build + target: "bun", + entrypoints: Object.values(router.routes), + bundle: true, + splitting: true, + naming: "rsc/[dir]/[name]-[hash].[ext]", // write to /rsc + plugins: [ + { + name: "rsc", + setup(build: any) { + // new hook: onBuild + // this is where we'd support various AST transforms in the future + build.onBuild( + { directive: "client" }, + (args: { + path: string; + resolveDir: string; + module: { + directive?: string; + id: string; + exports: string[]; + }; + }) => { + // per-build `context` object + // initialized to {} + build.context.clientModules = build.context.clientModules || {}; + build.context.clientModules[args.resolveDir + "/" + args.path] = true; + + // future APIs + // client references + const exports: any = {}; + for (const key in args.module.exports) { + exports[key] = { + $$typeof: Symbol.for("react.client.element"), + $$id: args.module.id, + $$async: true, + }; + } + return { + loader: "object", + exports, + }; + }, + ); + }, + }, + ], + }) + .then(context => ({ + entrypoints: ["./client-entry.tsx", ...Object.keys(context.clientModules)], + target: "browser", + bundle: true, + splitting: true, + naming: "client/[dir]/[name]-[hash].[ext]", + plugins: [], + })) + .then(context => ({ + entrypoints: ["./ssr-entry.tsx", ...Object.keys(context.clientModules)], + target: "bun", + bundle: true, + splitting: true, + naming: "ssr/[dir]/[name]-[hash].[ext]", + plugins: [], + })) + .write("/.build");