- PVSM.RU - https://www.pvsm.ru -
В пятой версии сборщика Webpack появился набор плагинов для обмена модулями между Javascript приложениями.
Эта статья — краткое описание и пример на основе двух небольших приложений построенных на фреймворке ReactJS.
Плагин Module Federation позволяет приложению экспортировать один или несколько модулей в отдельный JS файл. Отличный способ строить микрофронтенд приложения. Сторонние приложения могут импортировать себе готовые модули, это могут быть например реакт компоненты. Причём, импорт зависимостей Webpack берёт на себя. Отличие от NPM в том, что импорт в runtime.
Приложение-источник в конфиге webpack явно указывает:
В HTML приложения-получателя импортируется JS файл приложения-источника как обычный JS скрипт:
<script src="http://source-app.com/export.js">
А в webpack конфиге, указывается какие модули брать из файла.
Приложение-источник должно прописать экспорт в настройках webpack.config.js
В настройках плагина указываем название экспортируемого контейнера, какие модули в него войдут и как будет называться файл.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
...
plugins: [
new ModuleFederationPlugin({
name: 'home',
library: { type: 'var', name: 'home' },
filename: 'export.js',
exposes: {
ProductCarousel: './src/ProductCarousel'
},
shared: ['react', 'react-dom', '@material-ui/core', '@material-ui/icons']
}),
]
};
Приложение-получатель
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://source-app.com/export.js"></script>
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
module.exports = {
...
plugins: [
new ModuleFederationPlugin({
remotes: {home: 'home' } //указываем контейнер
}),
]
};
import React from 'react';
import ProductCarousel from 'home/ProductCarousel';
function App() {
return (
<ProductCarousel />
);
}
export default App;
yarn install
yarn start
home (packages/home) | localhost [2]:3001/ |
search page (packages/search) | localhost [2]:3002/ |
nav (packages/nav) | localhost [2]:3003/ |
new ModuleFederationPlugin({
name: 'home',
library: { type: 'var', name: 'home' },
filename: 'remoteEntry.js', //в этом файле будет весь экспорт приложения для внешних получателей
remotes: {
nav: 'nav'
},
exposes: {
ProductCarousel: './src/ProductCarousel' //экспортируем один модуль, назовём его ProductCarousel
},
shared: ['react', 'react-dom', '@material-ui/core', '@material-ui/icons'] //это должно быть у получателя
}),
Вот как выглядит этот компонент в приложении home (я обвёл его красной рамкой)
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://localhost:3003/remoteEntry.js"></script>
<script src="http://localhost:3001/remoteEntry.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
module.exports = {
...
plugins: [
new ModuleFederationPlugin({
name: 'search',
library: { type: 'var', name: 'search' },
filename: 'remoteEntry.js',
remotes: {
nav: 'nav',
home: 'home'
},
exposes: {
},
shared: ['react', 'react-dom', '@material-ui/core', '@material-ui/icons']
}),
import ProductCarousel from 'home/ProductCarousel';
function App() {
return (
<Container fixed>
<CssBaseline />
<Header />
<Typography variant="h3">
Search Page.
</Typography>
<ProductCarousel />
</Container>
);
}
Было | Стало |
---|---|
Автор: Артём
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/354034
Ссылки в тексте:
[1] github.com/jherr/wp5-intro-video-code: https://github.com/jherr/wp5-intro-video-code
[2] localhost: http://localhost
[3] webpack.js.org/concepts/module-federation: https://webpack.js.org/concepts/module-federation/
[4] indepth.dev/webpack-5-module-federation-a-game-changer-in-javascript-architecture: https://indepth.dev/webpack-5-module-federation-a-game-changer-in-javascript-architecture/
[5] youtu.be/D3XYAx30CNc: https://youtu.be/D3XYAx30CNc
[6] Источник: https://habr.com/ru/post/506634/?utm_source=habrahabr&utm_medium=rss&utm_campaign=506634
Нажмите здесь для печати.