diff --git a/README.md b/README.md index a2fe751..aada38e 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,70 @@ -# MFNG - A React Server Components Playground +# MFNG -## Motivation +⚗️ A Minimal React Server Components Bundler & Library -### Exploring Possibilities for Next-Generation Microfrontends +## Packages -Do we still need to deploy microfrontends and their APIs (also known as BFFs) -independently of the main app? Or can we instead compose them at build-time -(lazily) and utilize server components to let them fetch their data on the -server? +MFNG offers two packages that together enable the building of a production-ready +RSC app. + +### `@mfng/core` + +This package contains the essential building blocks required on both the server +and the client to create a streaming, server-side rendered, and properly +hydrated RSC app. It also provides utilities that are needed for server-centric, +client-side navigation. + +↪ +[Documentation](https://github.com/unstubbable/mfng/blob/main/packages/core/README.md) + +### `@mfng/webpack-rsc` + +This package provides a set of Webpack loaders and plugins required for building +an RSC application bundle for the browser, as well as for the server. The server +bundle can be deployed to any serverless, edge, or Node.js-based environment. +`@mfng/webpack-rsc` can be used standalone as an RSC bundling solution or in +conjunction with `@mfng/core`. + +↪ +[Documentation](https://github.com/unstubbable/mfng/blob/main/packages/webpack-rsc/README.md) ## Features -- [x] Streaming fast - [x] React server components - [x] Server-side rendering -- [x] Client components loaded as separate chunks +- [x] Client components, lazily loaded as separate chunks - [x] Server actions - - [x] passed from server to client - - [x] imported from client - - [x] inline `'use server'` directive + - [x] passed as props from the server to the client + - [x] imported from the client + - [x] top-level functions/closures with inline `'use server'` directive - [ ] auto-binding of closed-over variables (not planned) - [x] Progressively enhanced form actions - [x] Suspensy routing -- [x] Development server - [x] Production builds +- [x] Development server - [x] Serverless deployment examples - using a [Cloudflare Worker](https://workers.cloudflare.com) - using a [Vercel Edge Function](https://vercel.com/docs/functions/edge-functions) - using an [AWS Lambda Function](https://aws.amazon.com/lambda/), with [AWS CloudFront](https://aws.amazon.com/cloudfront/) as CDN -- [x] Support [poisoned imports][] -- [ ] Microfrontend composition demo +- [x] Support for + [poisoned imports](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md#poisoned-imports) +- [x] Support for the [Vercel AI SDK](https://sdk.vercel.ai/docs) +- [ ] Partial prerendering - [ ] Advanced routing -## Getting Started - -```sh -npm install -``` - -```sh -npm run dev -``` - -Open http://localhost:3000 - -## Deployment - -To deploy the workers to your own workers.dev domain, first create a -[Cloudflare API Token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/), -then run: - -```sh -CLOUDFLARE_API_TOKEN= npm run deploy -``` - -### Deploying via GitHub Actions - -To deploy via GitHub Actions, follow these steps: - -1. Fork the repository. -2. Create a new - [environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) - with the name "Cloudflare Workers". -3. Add the environment secret `CLOUDFLARE_API_TOKEN` using your own token as the - value. -4. Push a commit to the `main` branch. +## Name Origin ---- +The name MFNG stands for "Microfrontends Next Generation". The project was +originally motivated by the following question: -_Please let me know in the issues if any of these steps do not work for you._ +> Do we still need to deploy microfrontends and their APIs (also known as BFFs - +> Backend for Frontends) independently of the main app? Or can we integrate them +> at build-time, though dynamically composed at run-time, and allow them to use +> server components to fetch their data on the server? -[poisoned imports]: - https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md#poisoned-imports +It has since evolved into a general-purpose RSC library, not specifically +targeted at the microfrontends use case... until we explore some form of +federation integration, as pioneered by +[federated-rsc](https://github.com/jacob-ebey/federated-rsc/), perhaps. diff --git a/package-lock.json b/package-lock.json index 95a4266..c8ab408 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19727,7 +19727,7 @@ }, "packages/core": { "name": "@mfng/core", - "version": "3.0.0", + "version": "4.0.0", "license": "MIT", "dependencies": { "htmlescape": "^1.1.1" @@ -19748,7 +19748,7 @@ }, "packages/webpack-rsc": { "name": "@mfng/webpack-rsc", - "version": "3.0.1", + "version": "4.0.0", "license": "MIT", "dependencies": { "@babel/core": "^7.21.3", diff --git a/packages/core/README.md b/packages/core/README.md new file mode 100644 index 0000000..8fbf08c --- /dev/null +++ b/packages/core/README.md @@ -0,0 +1,75 @@ +# `@mfng/core` + +⚠️ **Experimental** + +This package contains the essential building blocks required on both the server +and the client to create a streaming, server-side rendered, and properly +hydrated RSC app. It also provides utilities needed for server-centric, +client-side navigation. + +## Getting Started + +To use this library in your React Server Components project, follow these +high-level steps: + +1. Install the library along with React Canary: + +```sh +npm install @mfng/core react@canary react-dom@canary +``` + +2. Create a server entry that handles GET requests to create RSC app streams and + HTML streams, as well as POST requests for creating RSC action streams. + Optionally, add support for progressively enhanced forms. + +3. Create a client entry that hydrates the server-rendered app and fetches RSC + streams during navigation or when executing server actions. + +4. Set up your webpack config as described in the `@mfng/webpack-rsc` + [README](https://github.com/unstubbable/mfng/blob/main/packages/webpack-rsc/README.md). + +5. Create a simple dev server using [Hono](https://hono.dev) and + [tsx](https://github.com/privatenumber/tsx). + +## Building Blocks + +### Server + +#### `@mfng/core/server/rsc` + +- `createRscAppStream` +- `createRscActionStream` +- `createRscFormState` + +#### `@mfng/core/server/ssr` + +- `createHtmlStream` + +#### `@mfng/core/router-location-async-local-storage` + +- `routerLocationAsyncLocalStorage` + +### Client + +#### `@mfng/core/client/browser` + +- `hydrateApp` +- `callServer` (usually not directly needed, encapsulated by `hydrateApp`) +- `Router` (usually not directly needed, encapsulated by `hydrateApp`) + +#### `@mfng/core/client` + +- `useRouter` +- `Link` + +### Universal (Client & Server) + +#### `@mfng/core/use-router-location` + +- `useRouterLocation` + +## Putting It All Together + +I would recommend taking a look at the example apps. The +[AWS app](https://github.com/unstubbable/mfng/tree/main/apps/aws-app) has a +particularly clean setup. diff --git a/packages/core/package.json b/packages/core/package.json index e738644..ac5d506 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@mfng/core", - "version": "3.0.0", + "version": "4.0.0", "description": "Core server and client utilities for bootstrapping a React Server Components app", "repository": { "type": "git", diff --git a/packages/webpack-rsc/README.md b/packages/webpack-rsc/README.md index 5eb3e84..12f1eaf 100644 --- a/packages/webpack-rsc/README.md +++ b/packages/webpack-rsc/README.md @@ -2,9 +2,16 @@ ⚠️ **Experimental** -This library provides a set of Webpack loaders and plugins for integrating React -Server Components (RSC) and Server-Side Rendering (SSR) in a React application -that can be deployed to the edge. +This library provides a set of Webpack loaders and plugins required for building +a React Server Components (RSC) application bundle for the browser, as well as +for the server, with server-side rendering (SSR). + +The server bundle can be deployed to any serverless, edge, or Node.js-based +environment. + +`@mfng/webpack-rsc` can be used standalone as an RSC bundling solution or in +conjunction with +[`@mfng/core`](https://github.com/unstubbable/mfng/blob/main/packages/core/README.md). > Disclaimer: There are many moving parts involved in creating an RSC app that > also handles SSR, without using a framework like Next.js. This library only diff --git a/packages/webpack-rsc/package.json b/packages/webpack-rsc/package.json index 47ccff6..1329e33 100644 --- a/packages/webpack-rsc/package.json +++ b/packages/webpack-rsc/package.json @@ -1,6 +1,6 @@ { "name": "@mfng/webpack-rsc", - "version": "3.0.1", + "version": "4.0.0", "description": "A set of Webpack loaders and plugins for React Server Components", "repository": { "type": "git",