|
1 | 1 | # Plugin Architektura s Webpack5, NX a Angular 14+ (Ivy + AOT)
|
2 | 2 | ## Jak spustit:
|
3 |
| -- Vybuildit plugin a widget |
4 |
| - - `npm run build:all` |
5 |
| - - přetáhnout obsah složky `dist/apps` do `apps/shell/assets` (v assets tedy bude složka `plugins` a `widgets`) |
6 |
| - - a spustit aplikaci pomocí: `nx run shell:serve:production` |
7 |
| - - otevřít [aplikaci](http://localhost:4200) |
| 3 | +1. Vybuildit plugin a widget (mělo by být součástí gitu, lze přeskočit na krok 3.) |
| 4 | + 1. `npm run build:all` |
| 5 | +1. přetáhnout obsah složky `dist/apps` do `apps/shell/assets` (v assets tedy bude složka `plugins` a `widgets`) |
| 6 | +1. spustit aplikaci pomocí: `nx run shell:serve:production` |
| 7 | +1. otevřít [aplikaci](http://localhost:4200) |
8 | 8 | ---
|
9 |
| -- Alternativně lze vše servnout s hot reloadem: |
10 |
| - - `npm run start:all` |
11 |
| - - otevřít [aplikaci](http://localhost:4200) |
| 9 | +1. Alternativně lze vše servnout s hot reloadem: |
| 10 | + 1. `npm run start:all` |
| 11 | +1. otevřít [aplikaci](http://localhost:4200) |
12 | 12 |
|
13 | 13 |
|
14 | 14 | ## Jak to funguje
|
15 |
| -- Využívá koncept webpacku zvaný [Module Federation](https://webpack.js.org/concepts/module-federation/) |
| 15 | +- Využívá [Module Federation](https://webpack.js.org/concepts/module-federation/) koncept webpacku |
16 | 16 | - Pro správné načítání modulů je nutné, aby webpack věděl, kde se daný modul nachází - k tomu slouží funkce `setRemoteDefinitions`, která se aktuálně volá při bootstrapu shell aplikace v `apps/shell/src/main.ts`
|
17 |
| - - **Tento manifest lze ale nastavit kdykoliv**, jediná podmínka je, aby se tak stalo ještě před tím, než se pokusíme naloadovat plugin pomoci funkce `loadRemoteModule` |
18 |
| -- Každý plugin si ve svém souboru `module-federation.config.js` může nastavit nekolik entry pointu v atributu `exposes`. Může to být modul, komponenta, cesty pro ng-router... |
19 |
| -- Aktuálně se například v `apps/shell/src/app/app.routes.ts` stahuje modul pluginu calendar, který zaregistruje sve cesty do ng-routeru. |
| 17 | + - **Tento manifest lze ale nastavit kdykoliv**, jediná podmínka je, aby se tak stalo ještě před tím, než se pokusíme naloadovat modul pomoci funkce `loadRemoteModule` |
| 18 | +- Každý plugin si ve svém souboru `module-federation.config.js` může nastavit své entry pointy pomocí atributu `exposes`. Může to být modul, komponenta, cesty pro ng-router... |
| 19 | +- Aktuálně se například v `apps/shell/src/app/app.routes.ts` stahuje modul pluginu `calendar`, který zaregistruje své cesty do ng-routeru. |
20 | 20 | - Nyní jsem se nezabýval implementací pro správu pluginu, takže cesta `calendar` je hardcoded, není ovšem problém tyto cesty nastavit dynamicky, např. po fetchnuti z BE.
|
21 | 21 | - V aplikaci `apps/shell/src/app/app.component.ts` se take renderuji 2 komponenty - jedna z pluginu calendar a druha z widgetu, jež je standalone builditelna komponenta.
|
22 | 22 | - Opět je to zde mírně hardoced, ale analogicky jako s cestami `calendar` pluginu, není problém tyto informace nastavit dynamicky, např. po fetchnuti z BE.
|
23 | 23 |
|
24 | 24 |
|
25 | 25 | ## Výhody
|
26 |
| -- pro načtení pluginu se používá funkce z NX `@nrwl/angular/mf/loadRemoteModule`, ktere pod pokličkou pouzivaji webpack a jejich [ModuleFederation plugin](https://webpack.js.org/plugins/module-federation-plugin/) |
| 26 | +- pro načtení pluginu se používá funkce z NX `@nrwl/angular/mf/loadRemoteModule`, která pod pokličkou používá webpack a jejich [ModuleFederation plugin](https://webpack.js.org/plugins/module-federation-plugin/) |
27 | 27 | - heavy lifting tedy dělá NX, potažmo webpack
|
28 | 28 | - kompatibilní s NX incremental builds
|
29 | 29 | - Díky webpacku chunkování funguje rekurzivně - **lazy loading tedy funguje kdekoliv**, i v dynamicky načteném pluginu
|
30 | 30 | - Samostatné pluginy a widgety lze `servnout`, tím pádem je velmi jednoduchý jejich developement. Lze je take vybuildit a zazipovat pro účel pluginizace (_inspirace názvu z deduplikace_).
|
31 | 31 | - Možnost snadné implementace e2e testu na jednotlivé pluginy
|
32 | 32 |
|
33 | 33 | ## Nevyhody
|
34 |
| -- ??? |
| 34 | +- zatím jsem na nic neřešitelného nenarazil |
35 | 35 |
|
36 | 36 | ## NX's withModuleFederation
|
37 | 37 | - Opinionated wrapper na [ModuleFederationPlugin](https://webpack.js.org/plugins/module-federation-plugin/) webpacku
|
|
43 | 43 | - dependencies co vyčte z projectGraphu, tzn. pokud naimportuju nejakou knihovnu z monorepa, sam ji prida do sharovanych dependencies. Zpravidla je to žádoucí chování, lze tomu ale zabránit v configu.
|
44 | 44 |
|
45 | 45 | ## Verzování
|
46 |
| -- své verze si každý plugin a appka udržují ve svem `package.json` |
47 |
| -- appka nebo plugin si v souboru `module-federation.config.js` mohou dale specifikovat, ktere verze jednotlivych pluginu potrebuji, např.: |
| 46 | +- své verze si každý plugin a appka udržují ve svém `package.json` |
| 47 | +- appka nebo plugin si v souboru `module-federation.config.js` mohou dale specifikovat, které verze jednotlivých pluginu potřebují, např.: |
48 | 48 | ```js
|
49 | 49 | {
|
50 | 50 | // ...
|
|
53 | 53 | ]
|
54 | 54 | }
|
55 | 55 | ```
|
56 |
| -- Pokud dojde k neshodě smluvených verzí, upozorní nás webpack následujícím errorem: |
| 56 | +- Pokud dojde k neshodě smluvených verzí, upozorní nás webpack následujícím runtime errorem: |
57 | 57 | - `Unsatisfied version 2.0.0 from shell of shared singleton module @ng-mfa/shared/data-access/random (required >=1.0.0 <1.1.1)`
|
58 | 58 | - **requiredVersion** lze specifikovat v několika formátech:
|
59 | 59 | - standardní formát s ~ nebo ^, např.:
|
|
63 | 63 | - '>=1.0.0 <1.1.1', nebo-li verze od 1.0.0 (včetně) až 1.1.1 (vyjma)
|
64 | 64 |
|
65 | 65 | ## Commands
|
66 |
| -- novy plugin: |
| 66 | +- nový plugin: |
67 | 67 | - `npx nx g @nrwl/angular:remote plugins/<PLUGIN_NAME>`
|
68 |
| -- novy plugin/widget jako standalone component: |
| 68 | +- nový widget jako standalone component: |
69 | 69 | - `npx nx g @nrwl/angular:remote widgets/<WIDGET_NAME> --standalone`
|
70 | 70 |
|
71 | 71 | ## Source codes
|
72 |
| -- Zdrojový kod na NX implementaci pro **withModuleFederation** wrapper a **loadRemoteModule** - dynamické načítání modulů. |
73 |
| - - https://github.com/nrwl/nx/blob/master/packages/angular/mf/mf.ts |
| 72 | +- Zdroják je mnohdy lepší než dokumentace od NX, tak přikládám i url k těm stěžejním věcem |
| 73 | +- **withModuleFederation** wrapper: |
74 | 74 | - https://github.com/nrwl/nx/blob/master/packages/angular/src/utils/mf/with-module-federation.ts
|
| 75 | +- **loadRemoteModule** - dynamické načítání modulů. |
| 76 | + - https://github.com/nrwl/nx/blob/master/packages/angular/mf/mf.ts |
75 | 77 |
|
76 | 78 | ## TODO:
|
77 | 79 | - [x] verify lazy loading inside plugins works
|
|
0 commit comments