wu-framework 1.0.0
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/LICENSE +21 -0
- package/README.md +559 -0
- package/package.json +84 -0
- package/src/api/wu-simple.js +316 -0
- package/src/core/wu-app.js +192 -0
- package/src/core/wu-cache.js +374 -0
- package/src/core/wu-core.js +1296 -0
- package/src/core/wu-error-boundary.js +380 -0
- package/src/core/wu-event-bus.js +257 -0
- package/src/core/wu-hooks.js +348 -0
- package/src/core/wu-html-parser.js +280 -0
- package/src/core/wu-loader.js +271 -0
- package/src/core/wu-logger.js +119 -0
- package/src/core/wu-manifest.js +366 -0
- package/src/core/wu-performance.js +226 -0
- package/src/core/wu-plugin.js +213 -0
- package/src/core/wu-proxy-sandbox.js +153 -0
- package/src/core/wu-registry.js +130 -0
- package/src/core/wu-sandbox-pool.js +390 -0
- package/src/core/wu-sandbox.js +720 -0
- package/src/core/wu-script-executor.js +216 -0
- package/src/core/wu-snapshot-sandbox.js +184 -0
- package/src/core/wu-store.js +297 -0
- package/src/core/wu-strategies.js +241 -0
- package/src/core/wu-style-bridge.js +357 -0
- package/src/index.js +690 -0
- package/src/utils/dependency-resolver.js +326 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wu Framework Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
# 🚀 Wu Framework
|
|
2
|
+
|
|
3
|
+
**Universal Microfrontends Made Simple**
|
|
4
|
+
|
|
5
|
+
Wu Framework es la librería de microfrontends más simple y poderosa del mercado. **Framework agnostic, zero config, Shadow DOM nativo**.
|
|
6
|
+
|
|
7
|
+
## ✨ ¿Por qué Wu Framework?
|
|
8
|
+
|
|
9
|
+
| Característica | Module Federation | qiankun | **Wu Framework** |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| **Setup** | Webpack config complejo | Configuración manual | **Zero config** |
|
|
12
|
+
| **Framework Support** | React-first | Multi framework | **Cualquier framework** |
|
|
13
|
+
| **Bundler Required** | Solo Webpack 5 | Agnóstico pero complejo | **Ninguno** |
|
|
14
|
+
| **CSS Isolation** | Básico | CSS hacks | **Shadow DOM nativo** |
|
|
15
|
+
| **Runtime Config** | ❌ | Limitado | **✅ Completamente dinámico** |
|
|
16
|
+
| **API Complexity** | Alta | Media | **Súper simple** |
|
|
17
|
+
|
|
18
|
+
## 🎯 Instalación
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install wu-framework
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**¡Y ya está!** Sin webpack config, sin plugins, sin configuración.
|
|
25
|
+
|
|
26
|
+
## 🔥 Uso Básico
|
|
27
|
+
|
|
28
|
+
### Container App (Host)
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import { wu } from 'wu-framework';
|
|
32
|
+
|
|
33
|
+
// Inicializar con apps
|
|
34
|
+
wu.init({
|
|
35
|
+
apps: [
|
|
36
|
+
{ name: 'header', url: 'http://localhost:3001' },
|
|
37
|
+
{ name: 'sidebar', url: 'http://localhost:3002' },
|
|
38
|
+
{ name: 'content', url: 'http://localhost:3003' }
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Montar en el DOM
|
|
43
|
+
wu.mount('header', '#header-container');
|
|
44
|
+
wu.mount('sidebar', '#sidebar-container');
|
|
45
|
+
wu.mount('content', '#content-container');
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Micro App (Cualquier Framework)
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import { wu } from 'wu-framework';
|
|
52
|
+
|
|
53
|
+
// React
|
|
54
|
+
wu.define('header', {
|
|
55
|
+
mount: (container) => {
|
|
56
|
+
ReactDOM.render(<HeaderApp />, container);
|
|
57
|
+
},
|
|
58
|
+
unmount: (container) => {
|
|
59
|
+
ReactDOM.unmountComponentAtNode(container);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Vue
|
|
64
|
+
wu.define('sidebar', {
|
|
65
|
+
mount: (container) => {
|
|
66
|
+
createApp(SidebarApp).mount(container);
|
|
67
|
+
},
|
|
68
|
+
unmount: (container) => {
|
|
69
|
+
// Vue cleanup
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Vanilla JS
|
|
74
|
+
wu.define('content', {
|
|
75
|
+
mount: (container) => {
|
|
76
|
+
container.innerHTML = `
|
|
77
|
+
<h1>Content App</h1>
|
|
78
|
+
<p>Pure vanilla JavaScript!</p>
|
|
79
|
+
`;
|
|
80
|
+
},
|
|
81
|
+
unmount: (container) => {
|
|
82
|
+
container.innerHTML = '';
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 📋 Wu Manifest (wu.json)
|
|
88
|
+
|
|
89
|
+
Cada micro-app puede tener un archivo `wu.json` para configuración:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"name": "header-app",
|
|
94
|
+
"entry": "index.js",
|
|
95
|
+
"wu": {
|
|
96
|
+
"exports": {
|
|
97
|
+
"HeaderComponent": "./components/Header",
|
|
98
|
+
"useAuth": "./hooks/useAuth"
|
|
99
|
+
},
|
|
100
|
+
"imports": [
|
|
101
|
+
"shared.Button",
|
|
102
|
+
"shared.Theme"
|
|
103
|
+
],
|
|
104
|
+
"routes": ["/header", "/nav"],
|
|
105
|
+
"permissions": ["localStorage", "eventBus"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Component Sharing
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
// Exportar componentes
|
|
114
|
+
wu.define('shared', {
|
|
115
|
+
mount: (container) => {
|
|
116
|
+
// App shared con componentes reutilizables
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Usar componentes compartidos
|
|
121
|
+
const Button = await wu.use('shared.Button');
|
|
122
|
+
const Theme = await wu.use('shared.Theme');
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 🏗️ Arquitectura
|
|
126
|
+
|
|
127
|
+
Wu Framework usa **Shadow DOM nativo** para verdadero aislamiento:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
┌─────────────────────────────────────┐
|
|
131
|
+
│ Host Application │
|
|
132
|
+
├─────────────────────────────────────┤
|
|
133
|
+
│ ┌─────────────┐ ┌─────────────┐ │
|
|
134
|
+
│ │ #shadow-root│ │ #shadow-root│ │
|
|
135
|
+
│ │ ┌─────────┐│ │ ┌─────────┐│ │
|
|
136
|
+
│ │ │Header ││ │ │Sidebar ││ │
|
|
137
|
+
│ │ │(React) ││ │ │(Vue) ││ │
|
|
138
|
+
│ │ └─────────┘│ │ └─────────┘│ │
|
|
139
|
+
│ └─────────────┘ └─────────────┘ │
|
|
140
|
+
└─────────────────────────────────────┘
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Ventajas del Shadow DOM:
|
|
144
|
+
|
|
145
|
+
- ✅ **CSS completamente aislado** - No hay conflictos de estilos
|
|
146
|
+
- ✅ **JavaScript scope aislado** - Variables globales separadas
|
|
147
|
+
- ✅ **DOM encapsulado** - No hay interferencia entre apps
|
|
148
|
+
- ✅ **Performance nativo** - Sin overhead de hacks CSS
|
|
149
|
+
- ✅ **Debugging fácil** - Cada app en su propio DevTools tree
|
|
150
|
+
|
|
151
|
+
## 🎨 Ejemplos de Frameworks
|
|
152
|
+
|
|
153
|
+
### React + TypeScript
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
// header-app/src/index.tsx
|
|
157
|
+
import React from 'react';
|
|
158
|
+
import ReactDOM from 'react-dom';
|
|
159
|
+
import { wu } from 'wu-framework';
|
|
160
|
+
|
|
161
|
+
const HeaderApp: React.FC = () => (
|
|
162
|
+
<header className="app-header">
|
|
163
|
+
<h1>Header App (React)</h1>
|
|
164
|
+
</header>
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
wu.define('header', {
|
|
168
|
+
mount: (container: HTMLElement) => {
|
|
169
|
+
ReactDOM.render(<HeaderApp />, container);
|
|
170
|
+
},
|
|
171
|
+
unmount: (container: HTMLElement) => {
|
|
172
|
+
ReactDOM.unmountComponentAtNode(container);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Vue 3 + Composition API
|
|
178
|
+
|
|
179
|
+
```vue
|
|
180
|
+
<!-- sidebar-app/src/App.vue -->
|
|
181
|
+
<template>
|
|
182
|
+
<aside class="app-sidebar">
|
|
183
|
+
<h2>Sidebar App (Vue)</h2>
|
|
184
|
+
<nav>
|
|
185
|
+
<ul>
|
|
186
|
+
<li v-for="item in items" :key="item.id">
|
|
187
|
+
{{ item.name }}
|
|
188
|
+
</li>
|
|
189
|
+
</ul>
|
|
190
|
+
</nav>
|
|
191
|
+
</aside>
|
|
192
|
+
</template>
|
|
193
|
+
|
|
194
|
+
<script setup>
|
|
195
|
+
import { ref } from 'vue';
|
|
196
|
+
|
|
197
|
+
const items = ref([
|
|
198
|
+
{ id: 1, name: 'Home' },
|
|
199
|
+
{ id: 2, name: 'About' },
|
|
200
|
+
{ id: 3, name: 'Contact' }
|
|
201
|
+
]);
|
|
202
|
+
</script>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
// sidebar-app/src/index.js
|
|
207
|
+
import { createApp } from 'vue';
|
|
208
|
+
import { wu } from 'wu-framework';
|
|
209
|
+
import App from './App.vue';
|
|
210
|
+
|
|
211
|
+
let app;
|
|
212
|
+
|
|
213
|
+
wu.define('sidebar', {
|
|
214
|
+
mount: (container) => {
|
|
215
|
+
app = createApp(App);
|
|
216
|
+
app.mount(container);
|
|
217
|
+
},
|
|
218
|
+
unmount: (container) => {
|
|
219
|
+
if (app) {
|
|
220
|
+
app.unmount();
|
|
221
|
+
app = null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Angular
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// content-app/src/main.ts
|
|
231
|
+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
232
|
+
import { wu } from 'wu-framework';
|
|
233
|
+
import { AppModule } from './app/app.module';
|
|
234
|
+
|
|
235
|
+
let platformRef: any;
|
|
236
|
+
|
|
237
|
+
wu.define('content', {
|
|
238
|
+
mount: async (container: HTMLElement) => {
|
|
239
|
+
// Crear elemento para Angular
|
|
240
|
+
const appElement = document.createElement('app-root');
|
|
241
|
+
container.appendChild(appElement);
|
|
242
|
+
|
|
243
|
+
// Bootstrap Angular
|
|
244
|
+
platformRef = await platformBrowserDynamic().bootstrapModule(AppModule);
|
|
245
|
+
},
|
|
246
|
+
unmount: (container: HTMLElement) => {
|
|
247
|
+
if (platformRef) {
|
|
248
|
+
platformRef.destroy();
|
|
249
|
+
platformRef = null;
|
|
250
|
+
}
|
|
251
|
+
container.innerHTML = '';
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Svelte
|
|
257
|
+
|
|
258
|
+
```js
|
|
259
|
+
// footer-app/src/index.js
|
|
260
|
+
import { wu } from 'wu-framework';
|
|
261
|
+
import App from './App.svelte';
|
|
262
|
+
|
|
263
|
+
let app;
|
|
264
|
+
|
|
265
|
+
wu.define('footer', {
|
|
266
|
+
mount: (container) => {
|
|
267
|
+
app = new App({
|
|
268
|
+
target: container,
|
|
269
|
+
props: {
|
|
270
|
+
name: 'Footer App'
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
unmount: (container) => {
|
|
275
|
+
if (app) {
|
|
276
|
+
app.$destroy();
|
|
277
|
+
app = null;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## 🛠️ API Reference
|
|
284
|
+
|
|
285
|
+
### Core API
|
|
286
|
+
|
|
287
|
+
```js
|
|
288
|
+
import { wu } from 'wu-framework';
|
|
289
|
+
|
|
290
|
+
// Inicializar framework
|
|
291
|
+
await wu.init({ apps: [...] });
|
|
292
|
+
|
|
293
|
+
// Montar app
|
|
294
|
+
await wu.mount('appName', '#container');
|
|
295
|
+
|
|
296
|
+
// Desmontar app
|
|
297
|
+
await wu.unmount('appName');
|
|
298
|
+
|
|
299
|
+
// Definir lifecycle
|
|
300
|
+
wu.define('appName', { mount, unmount });
|
|
301
|
+
|
|
302
|
+
// Usar componente compartido
|
|
303
|
+
const Component = await wu.use('app.Component');
|
|
304
|
+
|
|
305
|
+
// Obtener información
|
|
306
|
+
const info = wu.getAppInfo('appName');
|
|
307
|
+
const stats = wu.getStats();
|
|
308
|
+
|
|
309
|
+
// Limpiar framework
|
|
310
|
+
await wu.destroy();
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Utils API
|
|
314
|
+
|
|
315
|
+
```js
|
|
316
|
+
import { init, mount, define, use } from 'wu-framework';
|
|
317
|
+
|
|
318
|
+
// API de conveniencia
|
|
319
|
+
await init([{ name: 'app', url: 'http://localhost:3000' }]);
|
|
320
|
+
await mount('app', '#container');
|
|
321
|
+
define('app', { mount, unmount });
|
|
322
|
+
const Component = await use('shared.Button');
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Development API
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
import { dev } from 'wu-framework';
|
|
329
|
+
|
|
330
|
+
// Debugging
|
|
331
|
+
dev.enableDebug();
|
|
332
|
+
dev.inspect();
|
|
333
|
+
|
|
334
|
+
// Hot reload (desarrollo)
|
|
335
|
+
await dev.reload('appName');
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## 🔧 Configuración Avanzada
|
|
339
|
+
|
|
340
|
+
### Presets
|
|
341
|
+
|
|
342
|
+
```js
|
|
343
|
+
import { wu, presets } from 'wu-framework';
|
|
344
|
+
|
|
345
|
+
// Desarrollo
|
|
346
|
+
await wu.init(presets.development([
|
|
347
|
+
{ name: 'header', port: 3001 },
|
|
348
|
+
{ name: 'sidebar', port: 3002 }
|
|
349
|
+
]));
|
|
350
|
+
|
|
351
|
+
// Producción
|
|
352
|
+
await wu.init(presets.production([
|
|
353
|
+
{ name: 'header', url: 'https://header.myapp.com' },
|
|
354
|
+
{ name: 'sidebar', url: 'https://sidebar.myapp.com' }
|
|
355
|
+
]));
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Eventos
|
|
359
|
+
|
|
360
|
+
```js
|
|
361
|
+
import { events } from 'wu-framework';
|
|
362
|
+
|
|
363
|
+
// Escuchar eventos del ciclo de vida
|
|
364
|
+
events.onAppMounted((event) => {
|
|
365
|
+
console.log('App mounted:', event.detail.appName);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
events.onAppError((event) => {
|
|
369
|
+
console.error('App error:', event.detail);
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## 🌟 Ventajas Competitivas
|
|
374
|
+
|
|
375
|
+
### vs Module Federation
|
|
376
|
+
|
|
377
|
+
- ✅ **No requiere Webpack 5** - Funciona con cualquier bundler
|
|
378
|
+
- ✅ **Runtime configuration** - No necesita build-time config
|
|
379
|
+
- ✅ **Framework agnostic real** - No solo React
|
|
380
|
+
- ✅ **API más simple** - Menos boilerplate
|
|
381
|
+
|
|
382
|
+
### vs qiankun
|
|
383
|
+
|
|
384
|
+
- ✅ **Shadow DOM nativo** - No hacks CSS
|
|
385
|
+
- ✅ **Mejor DX** - DevTools integration
|
|
386
|
+
- ✅ **Sandbox más ligero** - Menos overhead
|
|
387
|
+
- ✅ **Component sharing** - Sistema declarativo
|
|
388
|
+
|
|
389
|
+
### vs single-spa
|
|
390
|
+
|
|
391
|
+
- ✅ **Zero config** - Sin setup complejo
|
|
392
|
+
- ✅ **Shadow DOM** - Aislamiento real
|
|
393
|
+
- ✅ **Manifest system** - Configuración declarativa
|
|
394
|
+
- ✅ **API moderna** - ES modules nativo
|
|
395
|
+
|
|
396
|
+
## 📦 Bundler Support
|
|
397
|
+
|
|
398
|
+
Wu Framework funciona con **cualquier bundler** o sin bundler:
|
|
399
|
+
|
|
400
|
+
### Vite
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
// vite.config.js
|
|
404
|
+
export default {
|
|
405
|
+
// Wu Framework funciona out-of-the-box con Vite
|
|
406
|
+
// No necesita configuración especial
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Webpack
|
|
411
|
+
|
|
412
|
+
```js
|
|
413
|
+
// webpack.config.js
|
|
414
|
+
module.exports = {
|
|
415
|
+
// Wu Framework funciona con cualquier versión de Webpack
|
|
416
|
+
// Sin plugins especiales requeridos
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Sin Bundler (ES Modules)
|
|
421
|
+
|
|
422
|
+
```html
|
|
423
|
+
<!-- Funciona directamente en el browser -->
|
|
424
|
+
<script type="module">
|
|
425
|
+
import { wu } from './node_modules/wu-framework/src/index.js';
|
|
426
|
+
|
|
427
|
+
wu.init({
|
|
428
|
+
apps: [{ name: 'app', url: './my-app' }]
|
|
429
|
+
});
|
|
430
|
+
</script>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## 🚀 Getting Started
|
|
434
|
+
|
|
435
|
+
### 1. Crear Container App
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
mkdir my-container-app
|
|
439
|
+
cd my-container-app
|
|
440
|
+
npm init -y
|
|
441
|
+
npm install wu-framework
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
```js
|
|
445
|
+
// index.js
|
|
446
|
+
import { wu } from 'wu-framework';
|
|
447
|
+
|
|
448
|
+
wu.init({
|
|
449
|
+
apps: [
|
|
450
|
+
{ name: 'header', url: 'http://localhost:3001' },
|
|
451
|
+
{ name: 'content', url: 'http://localhost:3002' }
|
|
452
|
+
]
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
wu.mount('header', '#header');
|
|
456
|
+
wu.mount('content', '#content');
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
```html
|
|
460
|
+
<!-- index.html -->
|
|
461
|
+
<!DOCTYPE html>
|
|
462
|
+
<html>
|
|
463
|
+
<head>
|
|
464
|
+
<title>Wu Framework Container</title>
|
|
465
|
+
</head>
|
|
466
|
+
<body>
|
|
467
|
+
<div id="header"></div>
|
|
468
|
+
<div id="content"></div>
|
|
469
|
+
|
|
470
|
+
<script type="module" src="index.js"></script>
|
|
471
|
+
</body>
|
|
472
|
+
</html>
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### 2. Crear Micro App
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
mkdir header-app
|
|
479
|
+
cd header-app
|
|
480
|
+
npm init -y
|
|
481
|
+
npm install wu-framework react react-dom
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
```js
|
|
485
|
+
// index.js
|
|
486
|
+
import React from 'react';
|
|
487
|
+
import ReactDOM from 'react-dom';
|
|
488
|
+
import { wu } from 'wu-framework';
|
|
489
|
+
|
|
490
|
+
const HeaderApp = () => (
|
|
491
|
+
<header style={{ background: '#f0f0f0', padding: '1rem' }}>
|
|
492
|
+
<h1>My Header App</h1>
|
|
493
|
+
</header>
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
wu.define('header', {
|
|
497
|
+
mount: (container) => {
|
|
498
|
+
ReactDOM.render(<HeaderApp />, container);
|
|
499
|
+
},
|
|
500
|
+
unmount: (container) => {
|
|
501
|
+
ReactDOM.unmountComponentAtNode(container);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
```json
|
|
507
|
+
// wu.json
|
|
508
|
+
{
|
|
509
|
+
"name": "header-app",
|
|
510
|
+
"entry": "index.js",
|
|
511
|
+
"wu": {
|
|
512
|
+
"exports": {
|
|
513
|
+
"HeaderComponent": "./components/Header"
|
|
514
|
+
},
|
|
515
|
+
"imports": [],
|
|
516
|
+
"routes": ["/header"]
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### 3. Servir Apps
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
# Terminal 1 - Container
|
|
525
|
+
cd my-container-app
|
|
526
|
+
npx serve -p 3000
|
|
527
|
+
|
|
528
|
+
# Terminal 2 - Header App
|
|
529
|
+
cd header-app
|
|
530
|
+
npx serve -p 3001
|
|
531
|
+
|
|
532
|
+
# Abrir http://localhost:3000
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
## 🤝 Contributing
|
|
536
|
+
|
|
537
|
+
Wu Framework es open source. ¡Contribuciones bienvenidas!
|
|
538
|
+
|
|
539
|
+
1. Fork el repositorio
|
|
540
|
+
2. Crear feature branch (`git checkout -b feature/amazing-feature`)
|
|
541
|
+
3. Commit cambios (`git commit -m 'Add amazing feature'`)
|
|
542
|
+
4. Push branch (`git push origin feature/amazing-feature`)
|
|
543
|
+
5. Abrir Pull Request
|
|
544
|
+
|
|
545
|
+
## 📄 License
|
|
546
|
+
|
|
547
|
+
MIT License - ver [LICENSE](LICENSE) para detalles.
|
|
548
|
+
|
|
549
|
+
## 🙏 Acknowledgments
|
|
550
|
+
|
|
551
|
+
- Inspirado por qiankun, single-spa, y Module Federation
|
|
552
|
+
- Construido con amor para la comunidad de microfrontends
|
|
553
|
+
- Gracias a todos los contributors
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
**🚀 Wu Framework - Universal Microfrontends Made Simple**
|
|
558
|
+
|
|
559
|
+
*Framework agnostic • Zero config • Shadow DOM • Runtime loading*
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wu-framework",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "🚀 Universal Microfrontends Framework - Framework agnostic, zero config, Shadow DOM isolation",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.js",
|
|
9
|
+
"./core": "./src/core/wu-core.js",
|
|
10
|
+
"./loader": "./src/core/wu-loader.js",
|
|
11
|
+
"./sandbox": "./src/core/wu-sandbox.js",
|
|
12
|
+
"./manifest": "./src/core/wu-manifest.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"dev": "node examples/dev-server.js",
|
|
16
|
+
"build": "echo 'No build step needed - ES modules ready'",
|
|
17
|
+
"test": "echo 'Tests coming soon'",
|
|
18
|
+
"lint": "echo 'Linting coming soon'",
|
|
19
|
+
"start": "npm run dev"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"microfrontends",
|
|
23
|
+
"micro-frontends",
|
|
24
|
+
"framework-agnostic",
|
|
25
|
+
"react",
|
|
26
|
+
"vue",
|
|
27
|
+
"angular",
|
|
28
|
+
"svelte",
|
|
29
|
+
"shadow-dom",
|
|
30
|
+
"universal",
|
|
31
|
+
"zero-config",
|
|
32
|
+
"runtime-loading",
|
|
33
|
+
"component-sharing",
|
|
34
|
+
"web-components"
|
|
35
|
+
],
|
|
36
|
+
"author": "Wu Framework Team",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/wu-framework/wu-framework.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/wu-framework/wu-framework/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://wu-framework.dev",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=14.0.0"
|
|
48
|
+
},
|
|
49
|
+
"browserslist": [
|
|
50
|
+
"defaults",
|
|
51
|
+
"not IE 11",
|
|
52
|
+
"supports es6-module"
|
|
53
|
+
],
|
|
54
|
+
"files": [
|
|
55
|
+
"src/",
|
|
56
|
+
"README.md",
|
|
57
|
+
"LICENSE"
|
|
58
|
+
],
|
|
59
|
+
"dependencies": {},
|
|
60
|
+
"devDependencies": {},
|
|
61
|
+
"peerDependencies": {},
|
|
62
|
+
"optionalDependencies": {},
|
|
63
|
+
"funding": {
|
|
64
|
+
"type": "github",
|
|
65
|
+
"url": "https://github.com/sponsors/wu-framework"
|
|
66
|
+
},
|
|
67
|
+
"wu": {
|
|
68
|
+
"framework": true,
|
|
69
|
+
"version": "1.0.0",
|
|
70
|
+
"features": [
|
|
71
|
+
"universal-microfrontends",
|
|
72
|
+
"shadow-dom-isolation",
|
|
73
|
+
"zero-configuration",
|
|
74
|
+
"framework-agnostic",
|
|
75
|
+
"runtime-loading",
|
|
76
|
+
"component-sharing"
|
|
77
|
+
],
|
|
78
|
+
"compatibility": {
|
|
79
|
+
"frameworks": ["react", "vue", "angular", "svelte", "vanilla"],
|
|
80
|
+
"bundlers": ["vite", "webpack", "rollup", "parcel", "esbuild"],
|
|
81
|
+
"browsers": ["chrome", "firefox", "safari", "edge"]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|