Български

Отключете силата на микро-фронтендите с JavaScript Module Federation в Webpack 5. Научете как да изграждате мащабируеми, лесни за поддръжка и независими уеб приложения.

JavaScript Module Federation с Webpack 5: Цялостно ръководство за микро-фронтенди

В постоянно развиващия се свят на уеб разработката, изграждането на големи и сложни приложения може да бъде обезсърчаваща задача. Традиционните монолитни архитектури често водят до увеличено време за разработка, затруднения при внедряване и предизвикателства в поддържането на качеството на кода. Микро-фронтендите се появиха като мощен архитектурен модел за справяне с тези предизвикателства, позволявайки на екипите да изграждат и внедряват независими части от по-голямо уеб приложение. Една от най-обещаващите технологии за прилагане на микро-фронтенди е JavaScript Module Federation, въведена в Webpack 5.

Какво са микро-фронтенди?

Микро-фронтендите са архитектурен стил, при който фронтенд приложението се разгражда на по-малки, независими единици, които могат да бъдат разработвани, тествани и внедрявани автономно от различни екипи. Всеки микро-фронтенд отговаря за конкретна бизнес област или функционалност, и те се сглобяват заедно по време на изпълнение, за да формират цялостния потребителски интерфейс.

Представете си го като компания: вместо да имате един огромен екип за разработка, имате няколко по-малки екипа, фокусирани върху конкретни области. Всеки екип може да работи независимо, което позволява по-бързи цикли на разработка и по-лесна поддръжка. Да вземем за пример голяма платформа за електронна търговия като Amazon; различни екипи може да управляват продуктовия каталог, пазарската количка, процеса на плащане и управлението на потребителски акаунти. Всички те биха могли да бъдат независими микро-фронтенди.

Предимства на микро-фронтендите:

Предизвикателства на микро-фронтендите:

Какво е JavaScript Module Federation?

JavaScript Module Federation е функция на Webpack 5, която ви позволява да споделяте код между отделно компилирани JavaScript приложения по време на изпълнение. Тя ви дава възможност да излагате части от вашето приложение като "модули", които могат да бъдат консумирани от други приложения, без да е необходимо да ги публикувате в централно хранилище като npm.

Мислете за Module Federation като за начин да създадете федеративна екосистема от приложения, където всяко приложение може да допринася със собствена функционалност и да консумира функционалност от други приложения. Това елиминира нуждата от зависимости по време на компилация (build-time) и позволява наистина независими внедрявания.

Например, екипът по дизайн система може да изложи UI компоненти като модули, а различни екипи на приложения могат да консумират тези компоненти директно от приложението на дизайн системата, без да е необходимо да ги инсталират като npm пакети. Когато екипът на дизайн системата актуализира компонентите, промените автоматично се отразяват във всички консумиращи приложения.

Ключови концепции в Module Federation:

Настройка на Module Federation с Webpack 5: Практическо ръководство

Нека разгледаме практически пример за настройка на Module Federation с Webpack 5. Ще създадем две прости приложения: Host (хост) приложение и Remote (отдалечено) приложение. Отдалеченото приложение ще изложи компонент, а хост приложението ще го консумира.

1. Настройка на проекта

Създайте две отделни директории за вашите приложения: `host` и `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. Конфигурация на отдалеченото приложение

В директорията `remote` създайте следните файлове:

src/index.js:

```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (

Отдалечено приложение

); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

src/RemoteComponent.jsx:

```javascript import React from 'react'; const RemoteComponent = () => (

Това е отдалечен компонент!

Рендиран от отдалеченото приложение.

); export default RemoteComponent; ```

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'], }, }; ```

Създайте `public/index.html` с основна HTML структура. Важен е елементът `

`

3. Конфигурация на хост приложението

В директорията `host` създайте следните файлове:

  • `src/index.js`: Входна точка за приложението.
  • `webpack.config.js`: Конфигурационен файл на Webpack.

src/index.js:

```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (

Хост приложение

Зареждане на отдалечен компонент...
}>
); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

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'], }, }; ```

Създайте `public/index.html` с основна HTML структура (подобно на отдалеченото приложение). Важен е елементът `

`

4. Инсталиране на Babel

И в директорията `host`, и в `remote` инсталирайте зависимостите на Babel:

```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```

5. Стартиране на приложенията

И в директорията `host`, и в `remote` добавете следния скрипт към `package.json`:

```json "scripts": { "start": "webpack serve" } ```

Сега стартирайте и двете приложения:

```bash cd remote npm start cd ../host npm start ```

Отворете браузъра си и отидете на `http://localhost:3000`. Трябва да видите хост приложението с рендиран в него отдалечен компонент.

Обяснение на ключови опции за конфигурация:

Напреднали техники с Module Federation

Module Federation предлага много разширени функции, които могат да ви помогнат да изградите още по-сложни микро-фронтенд архитектури.

Динамични Remotes

Вместо да кодирате твърдо URL адресите на отдалечените приложения в конфигурацията на Webpack, можете да ги зареждате динамично по време на изпълнение. Това ви позволява лесно да актуализирате местоположението на отдалечените приложения, без да се налага да прекомпилирате хост приложението.

Например, можете да съхранявате URL адресите на отдалечените приложения в конфигурационен файл или база данни и да ги зареждате динамично с помощта на JavaScript.

```javascript // В webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Да приемем, че remoteUrl е нещо като 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // ключът на module federation е, че отдалеченото приложение е // достъпно чрез името в remote resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

Сега можете да заредите хост приложението с параметър в заявката `?remote=http://localhost:3001/remoteEntry.js`

Версионирани споделени модули

Module Federation може автоматично да управлява версиите и дедупликацията на споделените модули, за да гарантира, че се зарежда само една съвместима версия на всеки модул. Това е особено важно при работа с големи и сложни приложения, които имат много зависимости.

Можете да посочите обхвата на версиите на всеки споделен модул в конфигурацията на Webpack.

```javascript // В webpack.config.js shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```

Персонализирани зареждащи модули (Loaders)

Module Federation ви позволява да дефинирате персонализирани зареждащи модули, които могат да се използват за зареждане на модули от различни източници или в различни формати. Това може да бъде полезно за зареждане на модули от CDN или от персонализиран регистър на модули.

Споделяне на състояние между микро-фронтенди

Едно от предизвикателствата на микро-фронтенд архитектурите е споделянето на състояние между различните микро-фронтенди. Има няколко подхода, които можете да предприемете, за да се справите с това предизвикателство:

Най-добри практики за внедряване на микро-фронтенди с Module Federation

Ето някои най-добри практики, които да имате предвид при внедряването на микро-фронтенди с Module Federation:

Примери от реалния свят за Module Federation в действие

Въпреки че конкретните казуси често са поверителни, ето някои обобщени сценарии, при които Module Federation може да бъде изключително полезен:

Заключение

JavaScript Module Federation в Webpack 5 предоставя мощен и гъвкав начин за изграждане на микро-фронтенд архитектури. Той ви позволява да споделяте код между отделно компилирани JavaScript приложения по време на изпълнение, което позволява независими внедрявания, технологично разнообразие и подобрена автономност на екипа. Като следвате най-добрите практики, очертани в това ръководство, можете да използвате Module Federation за изграждане на мащабируеми, лесни за поддръжка и иновативни уеб приложения.

Бъдещето на фронтенд разработката несъмнено клони към модулни и разпределени архитектури. Module Federation предоставя ключов инструмент за изграждането на тези модерни системи, позволявайки на екипите да създават сложни приложения с по-голяма скорост, гъвкавост и устойчивост. С узряването на технологията можем да очакваме да се появят още по-иновативни случаи на употреба и най-добри практики.