Atraskite mikro-priekinių sistemų galią su JavaScript modulių federacija Webpack 5. Išmokite kurti mastelio keitimui pritaikomas, prižiūrimas ir nepriklausomas žiniatinklio programas.
JavaScript modulių federacija su Webpack 5: išsamus mikro-priekinių sistemų vadovas
Nuolat besikeičiančiame žiniatinklio kūrimo pasaulyje didelių ir sudėtingų programų kūrimas gali būti didžiulis iššūkis. Tradicinės monolitinės architektūros dažnai lemia ilgesnį kūrimo laiką, diegimo kliūtis ir iššūkius palaikant kodo kokybę. Mikro-priekinės sistemos (angl. micro-frontends) iškilo kaip galingas architektūrinis modelis šiems iššūkiams spręsti, leidžiantis komandoms kurti ir diegti nepriklausomas didesnės žiniatinklio programos dalis. Viena iš perspektyviausių technologijų mikro-priekinėms sistemoms įgyvendinti yra JavaScript modulių federacija, pristatyta „Webpack 5“.
Kas yra mikro-priekinės sistemos?
Mikro-priekinės sistemos yra architektūrinis stilius, kai priekinės sistemos (angl. frontend) programa yra suskaidoma į mažesnius, nepriklausomus vienetus, kuriuos gali savarankiškai kurti, testuoti ir diegti skirtingos komandos. Kiekviena mikro-priekinė sistema yra atsakinga už konkretų verslo domeną ar funkciją, ir jos yra sujungiamos vykdymo metu (angl. runtime), kad sudarytų vientisą vartotojo sąsają.
Pagalvokite apie tai kaip apie įmonę: vietoj vienos didžiulės kūrėjų komandos turite kelias mažesnes komandas, kurios koncentruojasi į konkrečias sritis. Kiekviena komanda gali dirbti nepriklausomai, kas leidžia greičiau vykdyti kūrimo ciklus ir palengvina priežiūrą. Pavyzdžiui, didelėje elektroninės prekybos platformoje, tokioje kaip „Amazon“, skirtingos komandos gali valdyti produktų katalogą, pirkinių krepšelį, atsiskaitymo procesą ir vartotojo paskyros valdymą. Visa tai galėtų būti nepriklausomos mikro-priekinės sistemos.
Mikro-priekinių sistemų privalumai:
- Nepriklausomas diegimas: Komandos gali diegti savo mikro-priekines sistemas nepriklausomai, nepaveikdamos kitų programos dalių. Tai sumažina diegimo riziką ir leidžia greičiau išleisti naujas versijas.
- Technologijų agnostiškumas: Skirtingos mikro-priekinės sistemos gali būti kuriamos naudojant skirtingas technologijas ar karkasus (pvz., „React“, „Angular“, „Vue.js“). Tai leidžia komandoms pasirinkti geriausią technologiją konkretiems poreikiams ir palaipsniui diegti naujas technologijas, nereikalaujant perrašyti visos programos. Įsivaizduokite, kad viena komanda naudoja „React“ produktų katalogui, kita – „Vue.js“ rinkodaros puslapiams, o trečia – „Angular“ atsiskaitymo procesui.
- Didesnė komandų autonomija: Komandos visiškai atsako už savo mikro-priekines sistemas, o tai suteikia daugiau autonomijos, greitesnį sprendimų priėmimą ir didesnį kūrėjų produktyvumą.
- Padidintas mastelio keitimo lankstumas: Mikro-priekinės sistemos leidžia keisti programos mastelį horizontaliai, diegiant atskiras mikro-priekines sistemas skirtinguose serveriuose.
- Kodo pakartotinis panaudojimas: Bendrinami komponentai ir bibliotekos gali būti lengvai naudojami tarp skirtingų mikro-priekinių sistemų.
- Lengvesnė priežiūra: Mažesnes kodo bazes paprastai lengviau suprasti, prižiūrėti ir derinti.
Mikro-priekinių sistemų iššūkiai:
- Padidėjęs sudėtingumas: Kelių mikro-priekinių sistemų valdymas gali padidinti bendros architektūros sudėtingumą, ypač komunikacijos, būsenos valdymo ir diegimo srityse.
- Našumo pridėtinės išlaidos: Kelių mikro-priekinių sistemų įkėlimas gali sukelti našumo problemų, ypač jei jos nėra tinkamai optimizuotos.
- Bendrieji aspektai (angl. cross-cutting concerns): Spręsti tokius bendrus aspektus kaip autentifikacija, autorizacija ir temų pritaikymas mikro-priekinių sistemų architektūroje gali būti sudėtinga.
- Operacinės pridėtinės išlaidos: Reikia brandžių DevOps praktikų ir infrastruktūros, kad būtų galima valdyti kelių mikro-priekinių sistemų diegimą ir stebėseną.
Kas yra JavaScript modulių federacija?
JavaScript modulių federacija yra „Webpack 5“ funkcija, leidžianti dalytis kodu tarp atskirai sukompiliuotų JavaScript programų vykdymo metu. Ji suteikia galimybę atverti dalį jūsų programos kaip „modulius“, kuriuos gali naudoti kitos programos, nereikalaujant jų publikuoti centralizuotoje saugykloje, pavyzdžiui, npm.
Modulių federaciją galima įsivaizduoti kaip būdą sukurti federacinę programų ekosistemą, kurioje kiekviena programa gali prisidėti savo funkcionalumu ir naudoti kitų programų funkcionalumą. Tai pašalina poreikį turėti priklausomybes kūrimo metu (angl. build-time) ir leidžia vykdyti išties nepriklausomus diegimus.
Pavyzdžiui, dizaino sistemos komanda gali atverti vartotojo sąsajos komponentus kaip modulius, o skirtingos programų komandos gali naudoti šiuos komponentus tiesiogiai iš dizaino sistemos programos, nereikalaujant jų diegti kaip npm paketų. Kai dizaino sistemos komanda atnaujina komponentus, pakeitimai automatiškai atsispindi visose juos naudojančiose programose.
Pagrindinės modulių federacijos sąvokos:
- Pagrindinė programa (Host): Pagrindinė programa, kuri naudoja nuotolinius modulius.
- Nuotolinė programa (Remote): Programa, kuri atveria modulius, skirtus naudoti kitoms programoms.
- Bendrinami moduliai (Shared Modules): Moduliai, kurie yra bendrinami tarp pagrindinės ir nuotolinės programos (pvz., „React“, „Lodash“). Modulių federacija gali automatiškai tvarkyti versijų valdymą ir dublikatų šalinimą, kad būtų įkelta tik viena kiekvieno modulio versija.
- Atverti moduliai (Exposed Modules): Konkretūs moduliai iš nuotolinės programos, kurie yra prieinami naudoti kitoms programoms.
- RemoteEntry.js: „Webpack“ sugeneruotas failas, kuriame yra metaduomenys apie nuotolinės programos atvertus modulius. Pagrindinė programa naudoja šį failą, kad atrastų ir įkeltų nuotolinius modulius.
Modulių federacijos nustatymas su Webpack 5: praktinis vadovas
Panagrinėkime praktinį pavyzdį, kaip nustatyti modulių federaciją su „Webpack 5“. Sukursime dvi paprastas programas: pagrindinę (Host) programą ir nuotolinę (Remote) programą. Nuotolinė programa atvers komponentą, o pagrindinė programa jį naudos.
1. Projekto paruošimas
Sukurkite du atskirus katalogus savo programoms: `host` ir `remote`.
```bash mkdir host remote cd host npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom cd ../remote npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom ```2. Nuotolinės programos konfigūracija
`remote` kataloge sukurkite šiuos failus:
- `src/index.js`: Programos įvesties taškas.
- `src/RemoteComponent.jsx`: Komponentas, kuris bus atvertas.
- `webpack.config.js`: „Webpack“ konfigūracijos failas.
src/index.js:
```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (Remote Application
src/RemoteComponent.jsx:
```javascript import React from 'react'; const RemoteComponent = () => (Tai yra nuotolinis komponentas!
Atvaizduotas iš nuotolinės programos.
webpack.config.js:
```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3001, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'remote', filename: 'remoteEntry.js', exposes: { './RemoteComponent': './src/RemoteComponent', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```Sukurkite `public/index.html` su bazine HTML struktūra. Svarbu, kad būtų `
`3. Pagrindinės programos konfigūracija
`host` kataloge sukurkite šiuos failus:
- `src/index.js`: Programos įvesties taškas.
- `webpack.config.js`: „Webpack“ konfigūracijos failas.
src/index.js:
```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (Host Application
webpack.config.js:
```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3000, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { remote: 'remote@http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```Sukurkite `public/index.html` su bazine HTML struktūra (panašiai kaip nuotolinėje programoje). Svarbu, kad būtų `
`4. Įdiekite „Babel“
Tiek `host`, tiek `remote` kataloguose įdiekite „Babel“ priklausomybes:
```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```5. Paleiskite programas
Tiek `host`, tiek `remote` kataloguose pridėkite šį scenarijų į `package.json`:
```json "scripts": { "start": "webpack serve" } ```Dabar paleiskite abi programas:
```bash cd remote npm start cd ../host npm start ```Atidarykite naršyklę ir eikite į `http://localhost:3000`. Turėtumėte pamatyti pagrindinę programą, kurios viduje atvaizduotas nuotolinis komponentas.
Pagrindinių konfigūracijos parinkčių paaiškinimas:
- `name`: Unikalus programos pavadinimas.
- `filename`: Failo, kuriame bus metaduomenys apie atvertus modulius, pavadinimas (pvz., `remoteEntry.js`).
- `exposes`: Modulių pavadinimų ir failų kelių sąryšis, nurodantis, kurie moduliai turi būti atverti.
- `remotes`: Nuotolinių programų pavadinimų ir URL adresų sąryšis, nurodantis, kur rasti kiekvienos nuotolinės programos `remoteEntry.js` failą.
- `shared`: Modulių, kurie turėtų būti bendrinami tarp pagrindinės ir nuotolinės programos, sąrašas. Parinktis `singleton: true` užtikrina, kad būtų įkeltas tik vienas kiekvieno bendrinamo modulio egzempliorius. Parinktis `eager: true` užtikrina, kad bendrinamas modulis būtų įkeltas nedelsiant (t. y. prieš bet kokius kitus modulius).
Pažangios modulių federacijos technikos
Modulių federacija siūlo daug pažangių funkcijų, kurios gali padėti kurti dar sudėtingesnes mikro-priekinių sistemų architektūras.
Dinaminės nuotolinės programos
Užuot griežtai nurodžius nuotolinių programų URL adresus „Webpack“ konfigūracijoje, galite juos įkelti dinamiškai vykdymo metu. Tai leidžia lengvai atnaujinti nuotolinių programų vietą, nereikalaujant perkurti pagrindinės programos.
Pavyzdžiui, galite saugoti nuotolinių programų URL adresus konfigūracijos faile arba duomenų bazėje ir įkelti juos dinamiškai naudojant JavaScript.
```javascript // webpack.config.js faile remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Tarkime, remoteUrl yra kažkas panašaus į 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // modulių federacijos esmė yra ta, kad nuotolinė programa yra // pasiekiama naudojant pavadinimą, nurodytą nuotolinėje programoje resolve(window.remote); }; document.head.appendChild(script); })`, }, ```Dabar galite įkelti pagrindinę programą su užklausos parametru `?remote=http://localhost:3001/remoteEntry.js`
Bendrinami moduliai su versijavimu
Modulių federacija gali automatiškai tvarkyti bendrinamų modulių versijavimą ir dublikatų šalinimą, kad būtų įkelta tik viena suderinama kiekvieno modulio versija. Tai ypač svarbu dirbant su didelėmis ir sudėtingomis programomis, turinčiomis daug priklausomybių.
Galite nurodyti kiekvieno bendrinamo modulio versijų diapazoną „Webpack“ konfigūracijoje.
```javascript // webpack.config.js faile shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```Individualūs modulių įkėlėjai
Modulių federacija leidžia apibrėžti individualius modulių įkėlėjus, kuriuos galima naudoti moduliams iš skirtingų šaltinių ar skirtingais formatais įkelti. Tai gali būti naudinga įkeliant modulius iš CDN arba iš individualaus modulių registro.
Būsenos bendrinimas tarp mikro-priekinių sistemų
Vienas iš mikro-priekinių sistemų architektūrų iššūkių yra būsenos bendrinimas tarp skirtingų mikro-priekinių sistemų. Yra keletas būdų, kaip spręsti šį iššūkį:
- URL pagrįstas būsenos valdymas: Saugokite būseną URL adrese ir naudokite URL komunikacijai tarp mikro-priekinių sistemų. Tai paprastas ir tiesmukas metodas, tačiau jis gali tapti nepatogus esant sudėtingai būsenai.
- Individualūs įvykiai (custom events): Naudokite individualius įvykius būsenos pokyčiams transliuoti tarp mikro-priekinių sistemų. Tai leidžia išlaikyti laisvą ryšį tarp sistemų, tačiau gali būti sudėtinga valdyti įvykių prenumeratas.
- Bendrinama būsenos valdymo biblioteka: Naudokite bendrinamą būsenos valdymo biblioteką, pvz., „Redux“ ar „MobX“, visos programos būsenai valdyti. Tai suteikia centralizuotą ir nuoseklų būdą valdyti būseną, tačiau gali sukelti priklausomybę nuo konkrečios bibliotekos.
- Pranešimų tarpininkas (Message Broker): Naudokite pranešimų tarpininką, pvz., „RabbitMQ“ ar „Kafka“, kad palengvintumėte komunikaciją ir būsenos bendrinimą tarp mikro-priekinių sistemų. Tai sudėtingesnis sprendimas, tačiau jis suteikia didelį lankstumą ir mastelio keitimo galimybes.
Geriausios praktikos diegiant mikro-priekines sistemas su modulių federacija
Štai keletas geriausių praktikų, kurias verta prisiminti diegiant mikro-priekines sistemas su modulių federacija:
- Apibrėžkite aiškias ribas kiekvienai mikro-priekinei sistemai: Kiekviena mikro-priekinė sistema turėtų būti atsakinga už konkretų verslo domeną ar funkciją ir turėti aiškiai apibrėžtas sąsajas.
- Naudokite nuoseklų technologijų rinkinį: Nors modulių federacija leidžia naudoti skirtingas technologijas skirtingoms mikro-priekinėms sistemoms, paprastai geriau naudoti nuoseklų technologijų rinkinį, siekiant sumažinti sudėtingumą ir pagerinti priežiūrą.
- Nustatykite aiškius komunikacijos protokolus: Apibrėžkite aiškius protokolus, kaip mikro-priekinės sistemos turėtų sąveikauti tarpusavyje.
- Automatizuokite diegimo procesą: Automatizuokite diegimo procesą, kad užtikrintumėte, jog mikro-priekinės sistemos gali būti diegiamos nepriklausomai ir patikimai. Apsvarstykite galimybę naudoti CI/CD konvejerius ir infrastruktūros kaip kodo (IaC) įrankius.
- Stebėkite savo mikro-priekinių sistemų našumą: Stebėkite savo mikro-priekinių sistemų našumą, kad nustatytumėte ir pašalintumėte bet kokias našumo kliūtis. Naudokite tokius įrankius kaip „Google Analytics“, „New Relic“ ar „Datadog“.
- Įdiekite patikimą klaidų apdorojimą: Įdiekite patikimą klaidų apdorojimą, kad užtikrintumėte, jog jūsų programa yra atspari gedimams.
- Taikykite decentralizuotą valdymo modelį: Suteikite komandoms galią priimti sprendimus dėl savo mikro-priekinių sistemų, išlaikant bendrą nuoseklumą ir kokybę.
Realaus pasaulio modulių federacijos pavyzdžiai
Nors konkretūs atvejų tyrimai dažnai yra konfidencialūs, štai keletas apibendrintų scenarijų, kur modulių federacija gali būti nepaprastai naudinga:
- Elektroninės prekybos platformos: Kaip minėta anksčiau, didelės el. prekybos platformos gali naudoti modulių federaciją, kad sukurtų nepriklausomas mikro-priekines sistemas produktų katalogui, pirkinių krepšeliui, atsiskaitymo procesui ir vartotojo paskyros valdymui. Tai leidžia skirtingoms komandoms dirbti su šiomis funkcijomis nepriklausomai ir diegti jas nepaveikiant kitų programos dalių. Pasaulinė platforma galėtų pritaikyti funkcijas skirtingiems regionams per nuotolinius modulius.
- Finansinių paslaugų programos: Finansinių paslaugų programos dažnai turi sudėtingas vartotojo sąsajas su daugybe skirtingų funkcijų. Modulių federacija gali būti naudojama kuriant nepriklausomas mikro-priekines sistemas skirtingiems sąskaitų tipams, prekybos platformoms ir ataskaitų skydeliams. Atitikties funkcijos, būdingos tam tikroms šalims, gali būti pateiktos per modulių federaciją.
- Sveikatos priežiūros portalai: Sveikatos priežiūros portalai gali naudoti modulių federaciją, kad sukurtų nepriklausomas mikro-priekines sistemas pacientų valdymui, vizitų planavimui ir medicininių įrašų prieigai. Skirtingi moduliai skirtingiems draudimo teikėjams ar regionams gali būti įkeliami dinamiškai.
- Turinio valdymo sistemos (TVS): TVS gali naudoti modulių federaciją, kad leistų vartotojams pridėti individualų funkcionalumą į savo svetaines, įkeliant nuotolinius modulius iš trečiųjų šalių kūrėjų. Skirtingos temos, įskiepiai ir valdikliai gali būti platinami kaip nepriklausomos mikro-priekinės sistemos.
- Mokymosi valdymo sistemos (MVS): MVS gali pasiūlyti kursus, sukurtus nepriklausomai ir integruotus į vieningą platformą per modulių federaciją. Atnaujinant atskirus kursus nereikia diegti pakeitimų visoje platformoje.
Išvada
JavaScript modulių federacija „Webpack 5“ suteikia galingą ir lankstų būdą kurti mikro-priekinių sistemų architektūras. Ji leidžia dalytis kodu tarp atskirai sukompiliuotų JavaScript programų vykdymo metu, sudarant sąlygas nepriklausomam diegimui, technologijų įvairovei ir didesnei komandų autonomijai. Laikydamiesi šiame vadove aprašytų geriausių praktikų, galite pasinaudoti modulių federacija kurdami mastelio keitimui pritaikomas, prižiūrimas ir inovatyvias žiniatinklio programas.
Priekinių sistemų kūrimo ateitis neabejotinai krypsta link modulinių ir paskirstytų architektūrų. Modulių federacija suteikia esminį įrankį šioms modernioms sistemoms kurti, leidžiantį komandoms greičiau, lanksčiau ir atspariau kurti sudėtingas programas. Technologijai bręstant, galime tikėtis dar daugiau inovatyvių jos panaudojimo atvejų ir geriausių praktikų atsiradimo.