@sbee/vite-federation 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +168 -0
- package/dist/index.js +1284 -0
- package/dist/index.mjs +1261 -0
- package/dist/runtime/index.d.ts +80 -0
- package/dist/runtime.js +176 -0
- package/dist/runtime.mjs +170 -0
- package/dist/satisfy.js +223 -0
- package/dist/satisfy.mjs +222 -0
- package/package.json +58 -0
- package/types/index.d.ts +334 -0
- package/types/pluginHooks.d.ts +4 -0
- package/types/viteDevServer.d.ts +22 -0
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# @sbee/vite-federation
|
|
2
|
+
|
|
3
|
+
Plugin Module Federation cho **Vite 8** (rolldown), tương thích với [Webpack Module Federation](https://webpack.js.org/concepts/module-federation/).
|
|
4
|
+
|
|
5
|
+
- **Zero runtime dependencies** — dùng `RolldownMagicString` và AST walker built-in của Vite/rolldown, không kéo theo `magic-string`, `oxc-parser`, hay `estree-walker`.
|
|
6
|
+
- **Runtime API** — host có thể tải remote động khi chạy mà **không cần** khai báo trước trong `vite.config.ts`.
|
|
7
|
+
- Hỗ trợ định dạng `esm`, `systemjs`, `var`; tương thích remote build bằng cả Vite lẫn Webpack.
|
|
8
|
+
|
|
9
|
+
## Cài đặt
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @sbee/vite-federation --save-dev
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`vite >= 7` là peer dependency (khuyến nghị Vite 8).
|
|
16
|
+
|
|
17
|
+
## Sử dụng qua config
|
|
18
|
+
|
|
19
|
+
Module Federation thường cần ít nhất 2 project: một `remote` (bên expose module) và một `host` (bên tiêu thụ module).
|
|
20
|
+
|
|
21
|
+
### Bước 1: Cấu hình remote
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
// vite.config.js — remote
|
|
25
|
+
import federation from '@sbee/vite-federation'
|
|
26
|
+
|
|
27
|
+
export default {
|
|
28
|
+
plugins: [
|
|
29
|
+
federation({
|
|
30
|
+
name: 'remote-app',
|
|
31
|
+
filename: 'remoteEntry.js',
|
|
32
|
+
// Các module được expose
|
|
33
|
+
exposes: {
|
|
34
|
+
'./Button': './src/Button.vue'
|
|
35
|
+
},
|
|
36
|
+
shared: ['vue']
|
|
37
|
+
})
|
|
38
|
+
],
|
|
39
|
+
build: {
|
|
40
|
+
// Module Federation yêu cầu target >= es2020
|
|
41
|
+
target: 'esnext'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Bước 2: Cấu hình host
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// vite.config.js — host
|
|
50
|
+
import federation from '@sbee/vite-federation'
|
|
51
|
+
|
|
52
|
+
export default {
|
|
53
|
+
plugins: [
|
|
54
|
+
federation({
|
|
55
|
+
name: 'host-app',
|
|
56
|
+
remotes: {
|
|
57
|
+
remote_app: 'http://localhost:5001/assets/remoteEntry.js'
|
|
58
|
+
},
|
|
59
|
+
shared: ['vue']
|
|
60
|
+
})
|
|
61
|
+
],
|
|
62
|
+
build: {
|
|
63
|
+
target: 'esnext'
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Bước 3: Dùng remote module trên host
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
import { defineAsyncComponent } from 'vue'
|
|
72
|
+
|
|
73
|
+
const RemoteButton = defineAsyncComponent(() => import('remote_app/Button'))
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<template>
|
|
78
|
+
<RemoteButton />
|
|
79
|
+
</template>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Runtime API — tải remote động không cần config
|
|
83
|
+
|
|
84
|
+
Khi host **không biết trước** danh sách remote (ví dụ URL đến từ backend, plugin marketplace, cấu hình động), dùng entry `@sbee/vite-federation/runtime`. Không cần khai báo `remotes` trong `vite.config.ts`.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { loadRemote } from '@sbee/vite-federation/runtime'
|
|
88
|
+
|
|
89
|
+
// Tải thẳng từ URL, không cần đăng ký trước
|
|
90
|
+
const Button = await loadRemote('https://remote.example.com/remoteEntry.js', './Button')
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Đăng ký trước rồi dùng theo tên
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { registerRemote, loadRemote } from '@sbee/vite-federation/runtime'
|
|
97
|
+
|
|
98
|
+
registerRemote('design-system', {
|
|
99
|
+
url: 'https://cdn.example.com/remoteEntry.js',
|
|
100
|
+
format: 'esm',
|
|
101
|
+
from: 'vite'
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const Modal = await loadRemote('design-system', './Modal')
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Preload & tải nhiều module cùng lúc
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { preloadRemote, loadRemoteModules } from '@sbee/vite-federation/runtime'
|
|
111
|
+
|
|
112
|
+
// Init sẵn remote, trả về handle để gọi .get() nhiều lần
|
|
113
|
+
const remote = await preloadRemote('design-system')
|
|
114
|
+
const Button = await remote.get('./Button')
|
|
115
|
+
|
|
116
|
+
// Tải nhiều module một lần
|
|
117
|
+
const { Header, Footer } = await loadRemoteModules(
|
|
118
|
+
'https://remote.example.com/remoteEntry.js',
|
|
119
|
+
{ Header: './Header', Footer: './Footer' }
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Gọi `loadRemote` / `preloadRemote` đồng thời với cùng một remote chỉ tải và init **đúng một lần** (promise được dedup), tránh trùng `<script>` hoặc double init.
|
|
124
|
+
|
|
125
|
+
### API reference
|
|
126
|
+
|
|
127
|
+
| Hàm | Mô tả |
|
|
128
|
+
| --- | --- |
|
|
129
|
+
| `loadRemote<T>(urlOrName, moduleName, config?)` | Tải một module từ remote. `urlOrName` là URL trực tiếp hoặc tên đã đăng ký. |
|
|
130
|
+
| `loadRemoteModules(urlOrName, { key: moduleName }, config?)` | Tải nhiều module cùng lúc, trả về object theo key. |
|
|
131
|
+
| `registerRemote(name, config)` | Đăng ký remote để dùng lại theo tên. Đồng bộ, chỉ lưu config. |
|
|
132
|
+
| `preloadRemote(name, config?)` | Tải & init remote, trả về `RemoteHandle` có `.get()`, `.init()`, `.inited`. |
|
|
133
|
+
| `provideShared(scope, packages)` | Đăng ký shared packages vào global share scope (dùng bởi host). |
|
|
134
|
+
| `getShareScope(scope?)` | Lấy global share scope hiện tại. |
|
|
135
|
+
|
|
136
|
+
`RemoteConfig`:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
interface RemoteConfig {
|
|
140
|
+
url: string | (() => Promise<string>)
|
|
141
|
+
format?: 'esm' | 'var' // mặc định 'esm'
|
|
142
|
+
from?: 'vite' | 'webpack' // mặc định 'vite'
|
|
143
|
+
shareScope?: string // mặc định 'default'
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Tùy chọn plugin
|
|
148
|
+
|
|
149
|
+
| Option | Kiểu | Mô tả |
|
|
150
|
+
| --- | --- | --- |
|
|
151
|
+
| `name` | `string` | Tên container. |
|
|
152
|
+
| `filename` | `string` | Tên file remote entry, mặc định `remoteEntry.js`. |
|
|
153
|
+
| `exposes` | `object` | Các module remote expose ra ngoài. |
|
|
154
|
+
| `remotes` | `object` | Các remote mà host tiêu thụ. |
|
|
155
|
+
| `shared` | `string[] \| object` | Các dependency dùng chung giữa host và remote. |
|
|
156
|
+
| `shareScope` | `string` | Tên share scope, mặc định `default`. |
|
|
157
|
+
|
|
158
|
+
## Build
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm run build
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Sinh ra bundle `esm` + `cjs` trong `dist/` kèm khai báo type cho entry `runtime`. Chạy test:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npx vitest run
|
|
168
|
+
```
|