From 8036a963a9c15fd003088a362abb84e15cd64c67 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Wed, 20 Nov 2024 13:23:40 +0800 Subject: [PATCH] docs(mf): polish docs --- .github/workflows/test.yml | 2 +- examples/module-federation/README.md | 76 +++++++ examples/module-federation/mf-host/README.md | 19 +- .../mf-react-component/README.md | 37 ++-- .../module-federation/mf-remote/README.md | 13 +- examples/module-federation/package.json | 8 +- .../en/guide/advanced/module-federation.mdx | 190 ++++++++++++------ website/docs/en/guide/advanced/storybook.mdx | 12 +- website/docs/en/guide/start/components/MF.mdx | 2 + website/docs/en/guide/start/glossary.mdx | 2 - 10 files changed, 249 insertions(+), 112 deletions(-) create mode 100644 examples/module-federation/README.md diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7e4bcf6b0..ad2cc8470 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -158,7 +158,7 @@ jobs: cache: 'pnpm' - name: Install Dependencies - run: pnpm install && cd ./tests && npx playwright install chromium + run: pnpm install && cd ./tests && pnpm playwright install chromium # only run benchmark in Ubuntu - name: Benchmarks (Vitest) diff --git a/examples/module-federation/README.md b/examples/module-federation/README.md new file mode 100644 index 000000000..f4a447605 --- /dev/null +++ b/examples/module-federation/README.md @@ -0,0 +1,76 @@ +# @examples/module-federation + +Check out [Module Federation Documentation](https://module-federation.io/) for the glossary of `consumer`, `producer`, `remote`, and `host`. + +## Packages + +In this example directory, there are three projects included, which are: + +### [mf-react-component](./mf-react-component/) + +**Role**: + +- Rslib project: producer +- Storybook: consumer + +A React component built with Rslib in the Module Federation format. It includes a Storybook configuration that demonstrates how to develop MF in Storybook. + +### [mf-remote](./mf-remote/) + +**Role**: producer + +A Module Federation remote module built with Rsbuild. It is consumed by [mf-react-component](./mf-react-component/) to show how a Rslib MF module could be consumed by another Rslib app while consuming other remote modules at the same time. + +Extra remote module is **optional**, it is used to demonstrate a complex Module Federation set up here. + +### [mf-host](./mf-host/) + +**Role**: consumer + +An Rsbuild app that consumes Module Federation remote module. + +## Development MF + +### With host app + +1. Start the remote module + +```bash +pnpm dev:remote +``` + +2. Start the Rslib MF module + +```bash +pnpm dev:rslib +``` + +3. Start the host app + +```bash +pnpm dev:host +``` + +Then access the host app at http://localhost:3000. + +### With Storybook + +1. Start the remote module + +```bash +pnpm dev:remote +``` + +2. Start the Rslib MF module + +```bash +pnpm dev:rslib +``` + +2. Start the host app + +```bash +pnpm dev:storybook +``` + +Then access the host app at http://localhost:6006. diff --git a/examples/module-federation/mf-host/README.md b/examples/module-federation/mf-host/README.md index e2ac46d1e..2b5a6d172 100644 --- a/examples/module-federation/mf-host/README.md +++ b/examples/module-federation/mf-host/README.md @@ -1,16 +1,13 @@ -# Rsbuild Project +# @examples/mf-host -Module Federation Host Example +> [!NOTE] +> Check out [README](../README.md) to see how to develop a Rslib MF project in a host app or Storybook. -## Setup +An Rsbuild app that consumes Module Federation remote module. -Install the dependencies: +## Usage -```bash -pnpm install -``` - -## Get Started +### Development Start the dev server: @@ -18,12 +15,16 @@ Start the dev server: pnpm dev ``` +### Build + Build the app for production: ```bash pnpm build ``` +### Preview + Preview the production build locally: ```bash diff --git a/examples/module-federation/mf-react-component/README.md b/examples/module-federation/mf-react-component/README.md index be4b26189..cfcd37ba2 100644 --- a/examples/module-federation/mf-react-component/README.md +++ b/examples/module-federation/mf-react-component/README.md @@ -1,37 +1,28 @@ # @examples/mf-react-component -This example demonstrates how to use Rslib to build a simple Module Federation React component. +> [!NOTE] +> Check out [README](../README.md) to see how to develop a Rslib MF project in a host app or Storybook. -### Usage +A React component built with Rslib in the Module Federation format. It includes a Storybook configuration that demonstrates how to develop MF in Storybook. -Dev MF module +## Usage -1. Start remote module which is loaded by Rslib module. +### Develop MF module -``` -nx run @examples/mf-remote:dev -``` - -2. Start MF dev mode. - -``` -nx run @examples/mf-react-component:dev +```bash +pnpm run dev ``` -3. Use Storybook to development component. +### Build and serve the dist in production mode -``` -nx run @examples/mf-react-component:storybook -``` - -Build +Build the project -``` -nx run @examples/mf-react-component:build +```bash +pnpm run build ``` -Build and Serve dist +Serve the dist -``` -nx run @examples/mf-react-component:serve +```bash +pnpm run serve ``` diff --git a/examples/module-federation/mf-remote/README.md b/examples/module-federation/mf-remote/README.md index 8f58a99c3..af4d6693b 100644 --- a/examples/module-federation/mf-remote/README.md +++ b/examples/module-federation/mf-remote/README.md @@ -1,14 +1,11 @@ -# Rsbuild Project +# @examples/mf-remote -Module Federation Remote Example +> [!NOTE] +> Check out [README](../README.md) to see how to develop a Rslib MF project in a host app or Storybook. -## Setup +A Module Federation remote module built with Rsbuild. It is consumed by [mf-react-component](./mf-react-component/) to show how a Rslib MF module could be consumed by another Rslib app while consuming other remote modules at the same time. -Install the dependencies: - -```bash -pnpm install -``` +Extra remote module is **optional**, it is used to demonstrate a complex Module Federation set up here. ## Get Started diff --git a/examples/module-federation/package.json b/examples/module-federation/package.json index 1272ba6a4..19bfaa251 100644 --- a/examples/module-federation/package.json +++ b/examples/module-federation/package.json @@ -1,10 +1,14 @@ { - "name": "@examples/mf", + "name": "@examples/module-federation", "private": true, "scripts": { - "dev:all": "pnpm dev:host & pnpm serve:lib & pnpm dev:remote", + "build:lib": "pnpm --filter mf-react-component run build", + "dev:all:host": "pnpm dev:host & pnpm dev:mf & pnpm dev:remote", + "dev:all:storybook": "pnpm dev:mf & pnpm dev:storybook & pnpm dev:remote", "dev:host": "pnpm --filter mf-host dev", + "dev:mf": "pnpm --filter mf-react-component dev", "dev:remote": "pnpm --filter mf-remote dev", + "dev:storybook": "pnpm --filter mf-react-component storybook", "serve:lib": "pnpm --filter mf-react-component run serve" } } diff --git a/website/docs/en/guide/advanced/module-federation.mdx b/website/docs/en/guide/advanced/module-federation.mdx index 7f70d00dc..2be11b3d6 100644 --- a/website/docs/en/guide/advanced/module-federation.mdx +++ b/website/docs/en/guide/advanced/module-federation.mdx @@ -1,10 +1,9 @@ -# Module Federation - -This chapter introduces how to build Module Federation output in Rslib. +import MF from '../start/components/MF.mdx'; +import { Tab, Tabs } from 'rspress/theme'; -## Glossary +# Module Federation -Module Federation is a JavaScript application divide-and-conquer architecture pattern (similar to server-side microservices) that allows you to share code and resources between multiple JavaScript applications (or Micro-Frontend). +This chapter introduces how to build [Module Federation](/guide/basic/output-format#mf) output in Rslib. ## Usage scenarios @@ -23,15 +22,15 @@ Module Federation can help you: ## Quick Start -First install the Module Federation Rsbuild Plugin (Rslib is based on Rsbuild). +First install the [Module Federation Rsbuild Plugin](https://www.npmjs.com/package/@module-federation/rsbuild-plugin). import { PackageManagerTabs } from '@theme'; -Add the plugin to the `rslib.config.ts` file: +Then add the plugin to the `rslib.config.ts` file: -```ts title='rslib.config.ts' +```ts title='rslib.config.ts' {8-43} import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; @@ -89,88 +88,147 @@ In the above example we added a new `format: 'mf'` , which will help you add an However, if you want this Rslib Module to consume other producers at the same time, do not use the build configuration `remote` parameter, because in other formats, this may cause errors, please refer to the example below using the Module Federation runtime -## Develop Module Federation remote module +## Develop MF remote module + +### Use Host App + +Rslib support developing Module Federation Rslib project with a host application. -Rslib support using Storybook to development Module Federation Rslib module. +#### 1. Start MF `dev` of library -### 1. Add Rslib `mf dev` command +Adding the `dev` command to the `package.json` file: ```json title="package.json" { - // ... "scripts": { "dev": "rslib mf dev" } } ``` - -Running the `dev` command can start the Module Federation development mode, -enabling consumption by either your **Host app** or the **Storybook app**, along +Then run the `dev` command can start the Module Federation development mode, +enabling consumption by your host app, along with Hot Module Replacement (HMR). -### 2. Install Storybook and Rsbuild Storybook addon + - +#### 2. Start Host App -`React App` +Set up the host app to consume the Rslib Module Federation library. Check out the [@module-federation/rsbuild-plugin +](https://www.npmjs.com/package/@module-federation/rsbuild-plugin) for more information. + +```ts title="rsbuild.config.ts" {8-24} +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; - +export default defineConfig({ + plugins: [ + pluginReact(), + pluginModuleFederation({ + name: 'rsbuild_host', + remotes: { + rslib: 'rslib@http://localhost:3001/mf/mf-manifest.json', + }, + shared: { + react: { + singleton: true, + }, + 'react-dom': { + singleton: true, + }, + }, + // Enable this when the output of Rslib is build under 'production' mode, while the host app is 'development'. + // Reference: https://lib.rsbuild.dev/guide/advanced/module-federation#faqs + shareStrategy: 'loaded-first', + }), + ], +}); +``` -`Vue App` +Then start the host app with `rsbuild dev`. - +### Use Storybook -This chapter will use `React App` as an example later. +Rslib support developing Module Federation Rslib project with Storybook. -### 3. Create `.storybook/main.ts` and add addons +#### 1. Start MF `dev` of library -```ts title=".storybook/main.ts" {13-38} -import { dirname, join } from 'node:path'; -import type { StorybookConfig } from 'storybook-react-rsbuild'; +Adding the `dev` command to the `package.json` file: -function getAbsolutePath(value: string): any { - return dirname(require.resolve(join(value, 'package.json'))); +```json title="package.json" +{ + "scripts": { + "dev": "rslib mf dev" + } } +``` -const config: StorybookConfig = { - stories: [ - '../stories/**/*.mdx', - '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', - ], - framework: { - name: getAbsolutePath('storybook-react-rsbuild'), - options: {}, - }, - addons: [ - { - name: getAbsolutePath('storybook-addon-rslib'), - options: { - rslib: { - include: ['**/stories/**'], - }, - }, - }, - { - name: '@module-federation/storybook-addon/preset', - options: { - // add your rslib module manifest here for storybook dev - // we have set dev.assetPrefix and server.port to 3001 in rslib.config.ts above - remotes: { - 'rslib-module': - // you can also add shared here for storybook app - // shared: {} - 'rslib-module@http://localhost:3001/mf/mf-manifest.json', - }, - }, - }, - ], -}; +Then run the `dev` command can start the Module Federation development mode, enabling consumption by Storybook, along with Hot Module Replacement (HMR). -export default config; -``` + -### 4. Start writing stories +#### 2. Set up Storybook configuration + +First, set up Storybook with the Rslib project. You can refer to the [Storybook chapter](/guide/advanced/storybook) to learn how to do this. In this chapter, we will use React as the framework for our example. + +1. Install the following Storybook addons to let Storybook work with Rslib Module Federation: + + - [storybook-addon-rslib](https://www.npmjs.com/package/storybook-addon-rslib): Storybook addon that let Storybook to load the Rslib config. + - [@module-federation/storybook-addon](https://www.npmjs.com/package/@module-federation/rsbuild-plugin): Storybook addon that set up the Module Federation config for Storybook. + + + +2. Then set up the Storybook configuration file `.storybook/main.ts`, specify the stories and addons, and set the framework with corresponding framework integration. + + ```ts title=".storybook/main.ts" {18-38} + import { dirname, join } from 'node:path'; + import type { StorybookConfig } from 'storybook-react-rsbuild'; + + function getAbsolutePath(value: string): any { + return dirname(require.resolve(join(value, 'package.json'))); + } + + const config: StorybookConfig = { + stories: [ + '../stories/**/*.mdx', + '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', + ], + framework: { + name: getAbsolutePath('storybook-react-rsbuild'), + options: {}, + }, + addons: [ + { + name: getAbsolutePath('storybook-addon-rslib'), + options: { + rslib: { + include: ['**/stories/**'], + }, + }, + }, + { + name: '@module-federation/storybook-addon/preset', + options: { + // add your rslib module manifest here for storybook dev + // we have set dev.assetPrefix and server.port to 3001 in rslib.config.ts above + remotes: { + 'rslib-module': + // you can also add shared here for storybook app + // shared: {} + 'rslib-module@http://localhost:3001/mf/mf-manifest.json', + }, + }, + }, + ], + }; + + export default config; + ``` + +#### 3. Writing stories with remote module + +Import components from remote module. ```ts title="stories/index.stories.tsx" {2-3} import React from 'react'; @@ -187,7 +245,7 @@ export default { export const Primary = {}; ``` -### 5. Add Module Federation types and stories into `tsconfig.json`. +#### 4. Add Module Federation types and stories into `tsconfig.json`. ```json title="tsconfig.json" { @@ -201,7 +259,7 @@ export const Primary = {}; } ``` -### 6. Start Storybook app +#### 5. Start Storybook app There you go, start Storybook with `npx storybook dev`. diff --git a/website/docs/en/guide/advanced/storybook.mdx b/website/docs/en/guide/advanced/storybook.mdx index baf52b342..442a97ad1 100644 --- a/website/docs/en/guide/advanced/storybook.mdx +++ b/website/docs/en/guide/advanced/storybook.mdx @@ -1,4 +1,5 @@ import { PackageManagerTabs } from '@theme'; +import { Tab, Tabs } from 'rspress/theme'; # Use Storybook @@ -39,7 +40,16 @@ Using React as an example, at this step you need to: }} /> - The dependencies may vary for each framework, please refer to the [Storybook Rsbuild documentation](https://storybook.rsbuild.dev/guide/framework.html) for details. In this React example, we will install [storybook-rsbuild-react](https://www.npmjs.com/package/storybook-react-rsbuild) as the framework integration. + The dependencies varies for each framework, please refer to the [Storybook Rsbuild documentation](https://storybook.rsbuild.dev/guide/framework.html) for details. In this React example, we will install [storybook-react-rsbuild](https://www.npmjs.com/package/storybook-react-rsbuild) as the framework integration. + + + + + + + + + 2. Configure the Storybook configuration file `.storybook/main.js`, specify the stories and addons, and set the framework with corresponding framework integration. diff --git a/website/docs/en/guide/start/components/MF.mdx b/website/docs/en/guide/start/components/MF.mdx index f717324cf..9fbaa0a5a 100644 --- a/website/docs/en/guide/start/components/MF.mdx +++ b/website/docs/en/guide/start/components/MF.mdx @@ -1 +1,3 @@ Module Federation is an architectural pattern for JavaScript application decomposition (similar to microservices on the server-side), allowing you to share code and resources between multiple JavaScript applications (or micro-frontends). + +See [Module Federation](https://rsbuild.dev/guide/advanced/module-federation) for more details. diff --git a/website/docs/en/guide/start/glossary.mdx b/website/docs/en/guide/start/glossary.mdx index 0b2637843..8e8f67dac 100644 --- a/website/docs/en/guide/start/glossary.mdx +++ b/website/docs/en/guide/start/glossary.mdx @@ -29,8 +29,6 @@ DTS stands for [TypeScript Declaration Files](https://www.typescriptlang.org/doc -See [Module Federation](https://rsbuild.dev/guide/advanced/module-federation) for more details. - ## More See more glossary in [Rsbuild - Glossary](https://rsbuild.dev/guide/start/glossary) and [Rspack - Glossary](https://rspack.dev/misc/glossary).