Skip to content

Commit

Permalink
feat: new plugin configuration (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangHongEn authored Aug 1, 2024
1 parent 35498b3 commit 8dfd32c
Show file tree
Hide file tree
Showing 31 changed files with 6,926 additions and 3,374 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules
/lib
dist
.DS_Store
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.organizeImports": true,
"source.fixAll": true
"source.organizeImports": "explicit",
"source.fixAll": "explicit"
},
"editor.formatOnSave": true
}
88 changes: 46 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Vite/Rollup plugin for Module Federation
# Vite plugin for Module Federation

## Reason why 🤔

Expand All @@ -10,64 +10,68 @@ This plugin makes Module Federation work together with [Vite](https://vitejs.dev
## Working implementations

### [React](https://github.com/module-federation/module-federation-examples/tree/master/vite-react-microfrontends)<br>

### [Svelte](https://github.com/module-federation/module-federation-examples/tree/master/vite-svelte-microfrontends)<br>
### [Vue](https://github.com/module-federation/module-federation-examples/tree/master/vite-vue-microfrontends)

### [Vue](https://github.com/module-federation/module-federation-examples/tree/master/vite-vue-microfrontends)

## Getting started 🚀

This plugin is based on top of [native-federation](https://www.npmjs.com/package/@softarc/native-federation) so this library is a [peer dependency](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#peerdependencies).

You need to extend the Vite configuration with this plugin:
https://module-federation.io/guide/basic/webpack.html

```typescript
```js
// vite.config.js
import { defineConfig } from 'vite';
import { federation } from '@module-federation/vite';
import { createEsBuildAdapter } from '@softarc/native-federation-esbuild';
import vue from '@vitejs/plugin-vue';
import { federation } from 'module-federation-vite';
import topLevelAwait from 'vite-plugin-top-level-await';

// https://vitejs.dev/config/
export default defineConfig(async ({ command }) => ({
server: {
fs: {
allow: ['.', '../shared'],
},
},
export default defineConfig({
plugins: [
await federation({
options: {
workspaceRoot: __dirname,
outputPath: 'dist',
tsConfig: 'tsconfig.json',
federationConfig: 'module-federation/federation.config.cjs',
verbose: false,
dev: command === 'serve',
federation({
name: 'bbc',
remotes: {
mfapp01: 'mfapp01@https://unpkg.com/mf-app-01@1.0.9/dist/remoteEntry.js',
remote2: 'mfapp02@https://unpkg.com/mf-app-02/dist/remoteEntry.js',
remote3:
'remote1@https://unpkg.com/react-manifest-example_remote1@1.0.6/dist/mf-manifest.json',
// "remote4": {
// entry: "http://localhost:5174/dd/remoteEntry.js",
// globalEntryName: "bb",
// type: "esm"
// }
},
exposes: {
App: './src/App.vue',
},
filename: 'dd/remoteEntry.js',
shared: {
vue: {},
react: {
requiredVersion: '18',
},
},
adapter: createEsBuildAdapter({ plugins: [...], }),
}),
[...]
// If you set build.target: "chrome89", you can remove this plugin
// topLevelAwait(),
],
}));
build: {
target: 'chrome89',
},
});
```

<br>

### Define configs
## roadmap

You need to define two different configurations in the `federationConfig` property.<br>
Here are two examples:

- [host](https://www.npmjs.com/package/@softarc/native-federation#configuring-hosts)
- [remote](https://www.npmjs.com/package/@softarc/native-federation#configuring-remotes)
<br><br>
- fix: remoteEntry and hostInit file names support hash generation
- feat: generate mf-manifest.json
- feat: support chrome plugin
- feat: support runtime plugins
- feat: download remote d.ts
- feat: generate d.ts
- feat: support @vitejs/plugin-legacy

### So far so good 🎉

Now you are ready to use Module Federation in Vite!

## Thanks 🤝

Big thanks to:

[Manfred Steyer](https://twitter.com/manfredsteyer), Speaker, Trainer, Consultant and Author with focus on Angular. Google Developer Expert (GDE) and Microsoft MVP.

who collaborate with me to make this possible.
29 changes: 29 additions & 0 deletions examples/rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Rsbuild Project

## Setup

Install the dependencies:

```bash
pnpm install
```

## Get Started

Start the dev server:

```bash
pnpm dev
```

Build the app for production:

```bash
pnpm build
```

Preview the production build locally:

```bash
pnpm preview
```
24 changes: 24 additions & 0 deletions examples/rust/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "examples-rust",
"version": "1.0.0",
"scripts": {
"dev": "rsbuild dev",
"build": "rsbuild build",
"preview": "rsbuild preview"
},
"dependencies": {
"@module-federation/enhanced": "0.2.5",
"antd": "^5.16.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3",
"vue": "^3.4.29"
},
"devDependencies": {
"@rsbuild/core": "0.7.10",
"@rsbuild/plugin-react": "0.7.10",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"typescript": "5.5.3"
}
}
48 changes: 48 additions & 0 deletions examples/rust/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';

export default defineConfig({
server: {
port: 5176,
open: true,
},
dev: {
// It is necessary to configure assetPrefix, and in the production environment, you need to configure output.assetPrefix
assetPrefix: 'http://localhost:5176',
},
tools: {
rspack: (config, { appendPlugins }) => {
config.output!.uniqueName = 'app1';
appendPlugins([
new ModuleFederationPlugin({
name: 'examples_rust',
remotes: {
viteRemote: 'http://localhost:5173/dd/remoteEntry.js',
},
remoteType: 'module',
exposes: {
'./app': './src/app.tsx',
},
manifest: {
filePath: 'manifestpath',
},
shared: [
'react',
'react-dom',
'vue',
// 'antd'
],
}),
]);
},
},
plugins: [
pluginReact({
splitChunks: {
react: false,
router: false,
},
}),
],
});
13 changes: 13 additions & 0 deletions examples/rust/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { applyVueInReact } from 'veaury';
import App from 'viteRemote/App';
const AppComponent = App.default;

export default function Button() {
return (
<div>
rust host
<hr />
<AppComponent />
</div>
);
}
11 changes: 11 additions & 0 deletions examples/rust/src/bootstrap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

//@ts-ignore
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App basename={'/'} />
</React.StrictMode>
);
1 change: 1 addition & 0 deletions examples/rust/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="@rsbuild/core/types" />
1 change: 1 addition & 0 deletions examples/rust/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import('./bootstrap');
16 changes: 16 additions & 0 deletions examples/rust/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"baseUrl": "./",
"target": "ES2020",
"lib": ["DOM", "ES2020"],
"module": "ESNext",
"jsx": "react-jsx",
"strict": true,
"skipLibCheck": true,
"isolatedModules": true,
"resolveJsonModule": true,
"moduleResolution": "bundler",
"useDefineForClassFields": true
},
"include": ["src"]
}
26 changes: 26 additions & 0 deletions examples/vite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

pnpm-lock.yaml

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
13 changes: 13 additions & 0 deletions examples/vite/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions examples/vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "examples-vite",
"version": "0.0.3",
"type": "module",
"scripts": {
"dev": "vite --force",
"build": "vite build",
"preview": "vite build && http-server --cors -p 5173 dist"
},
"dependencies": {
"module-federation-vite": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.2.0",
"vue": "^3.4.29",
"vue-router": "^4.4.0"
},
"devDependencies": {
"@swc/core": "~1.6.0",
"@vitejs/plugin-react": "^4.3.1",
"@vitejs/plugin-vue": "^5.0.5",
"vite": "^5.3.1",
"vite-plugin-top-level-await": "^1.4.1"
}
}
20 changes: 20 additions & 0 deletions examples/vite/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import R from 'react';
import RD from 'react-dom';
import Mfapp01App from 'mfapp01/App';
import Remote2App from 'remote2/App';
import Button from 'remote3/button';
import { ref } from 'vue';

console.log('share vue', ref);
console.log('share React', R, RD);

export default function () {
return (
<div>
vite react
<Button />
<Remote2App />
<Mfapp01App />
</div>
);
}
1 change: 1 addition & 0 deletions examples/vite/src/assets/vue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions examples/vite/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

//@ts-ignore
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Loading

0 comments on commit 8dfd32c

Please sign in to comment.