import { Badge } from "@theme";

# Quick Start Guide

Before reading this guide, please first read the [Setting Up Environment](./setting-up-env). This guide will lead you step by step to learn how to use Module Federation. We will build two independent Single Page Applications (SPAs) that will share components using Module Federation. If you encounter unfamiliar terms in the following text, please refer to the [Glossary](./glossary).

_<Badge text="Note:" type="info" /> <small>You can also use [Nx](https://nx.dev) to rapidly scaffold Module Federation projects for [React](../../practice/frameworks/react/using-nx-for-react) and [Angular](../../practice/frameworks/angular/using-nx-for-angular).</small>_

## Creating a Producer

### 1. Initializing the Project

Use [Rsbuild](https://rsbuild.dev/) to create a producer and call the following command:


import { PackageManagerTabs } from '@theme';

<PackageManagerTabs
  command={{
    npm: 'npm create rsbuild@latest',
    yarn: 'yarn create rsbuild',
    pnpm: 'pnpm create rsbuild@latest',
    bun: 'bun create rsbuild@latest',
  }}
/>


> Complete the project creation according to the prompts.

```bash
? Input target folder -> federation_provider
? Select framework -> React
? Select language -> TypeScript
```

### 2. Installing Module Federation Build Plugin

Following the steps above for initializing the project, we created a `React` project named `federation_provider`. Execute the following commands in sequence:

<PackageManagerTabs
  command={{
    npm: `
cd federation_provider
npm add @module-federation/enhanced
npm add @module-federation/rsbuild-plugin --save-dev
    `,
    yarn: `
cd federation_provider
yarn add @module-federation/enhanced
yarn add @module-federation/rsbuild-plugin --save-dev
    `,
    pnpm: `
cd federation_provider
pnpm add @module-federation/enhanced
pnpm add @module-federation/rsbuild-plugin --save-dev
    `,
    bun: `
cd federation_provider
bun add @module-federation/enhanced
bun add @module-federation/rsbuild-plugin --save-dev
    `,
  }}
/>

### 3. Exporting Modules by the Producer

> Change the entry file to asynchronous


```tsx
// Move src/index.tsx to a newly created src/bootstrap.tsx file
// src/index.tsx
import('./bootstrap');

// src/bootstrap.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);
```

> Add a Button Component

```tsx
// src/button.tsx
export default function Button() {
  return <div>Provider button</div>;
}
```

> Export the Button component through Module Federation

```typescript title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default defineConfig({
  plugins: [
    pluginReact(),
    pluginModuleFederation({
      name: 'federation_provider',
      exposes: {
        './button': './src/button.tsx',
      },
      shared: ['react', 'react-dom'],
    }),
  ],
  server: {
    port: 3000,
  },
});
```

### 4. Starting the Producer

<PackageManagerTabs
  command={{
    npm: `npm run dev`,
    yarn: `yarn run dev`,
    pnpm: `pnpm run dev`,
    bun: `bun run dev`,
  }}
/>

```zsh
➜  federation_provider npm run dev

> federation_provider@1.0.0 dev
> rsbuild dev --open

  Rsbuild v0.5.1

  > Local:    http://localhost:3000/
  > Network:  http://10.94.55.204:3000/
  > Network:  http://10.4.255.21:3000/

start   Compiling...
[ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3000/mf-manifest.json
```

After the project starts, the `Manifest Link: http://localhost:3000/mf-manifest.json` message appears, which is the manifest information link for Module Federation.

## Creating a Consumer

### 1. Initializing the Project

Use [Rsbuild](https://rsbuild.dev/) to create a consumer and call the following command:

<PackageManagerTabs
  command={{
    npm: 'npm create rsbuild@latest',
    yarn: 'yarn create rsbuild',
    pnpm: 'pnpm create rsbuild@latest',
    bun: 'bun create rsbuild@latest',
  }}
/>


> Complete the project creation according to the prompts.

```bash
? Input target folder -> federation_consumer
? Select framework -> React
? Select language -> TypeScript
```

### 2. Installing Module Federation Build Plugin

Following the steps above for initializing the project, we created a `React` project named `federation_consumer`. Execute the following commands in sequence:

<PackageManagerTabs
  command={{
    npm: `
cd federation_consumer
npm add @module-federation/enhanced
npm add @module-federation/rsbuild-plugin --save-dev
    `,
    yarn: `
cd federation_consumer
yarn add @module-federation/enhanced
yarn add @module-federation/rsbuild-plugin --save-dev
    `,
    pnpm: `
cd federation_consumer
pnpm add @module-federation/enhanced
pnpm add @module-federation/rsbuild-plugin --save-dev
    `,
    bun: `
cd federation_consumer
bun add @module-federation/enhanced
bun add @module-federation/rsbuild-plugin --save-dev
    `,
  }}
/>


### 3. Consuming the Producer

> Declare the `Module Federation` type path in `tsconfig.json`

```json
{
  "compilerOptions": {
    "paths":{
      "*": ["./@mf-types/*"]
    }
  }
}
````


> Add Module Federation plugin to consume remote modules

```typescript title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default defineConfig({
  plugins: [
    pluginReact(),
    pluginModuleFederation({
      name: 'federation_consumer',
      remotes: {
        federation_provider:
          'federation_provider@http://localhost:3000/mf-manifest.json',
      },
      shared: ['react', 'react-dom'],
    }),
  ],
  server: {
    port: 2000,
  },
});
```

> Change the entry to be asynchronous

```tsx
// Move src/index.tsx to a newly created src/bootstrap.tsx file
// src/index.tsx
import('./bootstrap');

// src/bootstrap.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);
```

> Reference the remote module

```tsx
import './App.css';
// The remote component provided by federation_provider
import ProviderButton from 'federation_provider/button';

const App = () => {
  return (
    <div className="content">
      <h1>Rsbuild with React</h1>
      <p>Start building amazing things with Rsbuild.</p>
      <div>
        <ProviderButton />
      </div>
    </div>
  );
};

export default App;
```

## Summary

Through the above process, you have completed the export of a component from a 'producer' for use by a 'consumer' based on Module Federation. Along the way, you have preliminarily used and understood the configurations of remotes, exposes, and shared in the Module Federation plugin.

If you wish to learn how to directly export and consume remote modules on Webpack and Rspack build tools, you can refer to: [Rspack Plugin](../basic/rspack), [Webpack Plugin](../basic/webpack)

## Next Steps

import NextSteps from '@components/NextSteps';
import Step from '@components/Step';

You may want to:

<NextSteps>
  <Step
    href="/guide/start/features"
    title="Feature Navigation"
    description="Learn about all the features provided by Module Federation"
  />
  <Step
    href="/configure"
    title="Review Configuration"
    description="Learn how to configure Module Federation"
  />
  <Step
    href="/guide/start/glossary"
    title="Glossary of Terms"
    description="Understand the concepts related to Module Federation"
  />
</NextSteps>
