Зачем вам нужно изучать принцип федерации модуля webpack5? потому чтоМикро интерфейсное решение EMPВ его основе лежит эта революционная функция, имеющая историческое прорывное значение. В этой статье вы сможете подробно изучить принцип федерации модулей webpack5, освоить краеугольный камень решения микроинтерфейса EMP, а также лучше использовать и применять решение микроинтерфейса EMP.
Недавно был официально выпущен webpack5, который запустил очень интересную новую функцию, а именно сегодняшний главный герой - Module Federation (далее mf), следующие три аспекта (что, как, где) будут исследованы вместе с вами Тайна этой функции .
1. Что такое
Module Federation дословно переводится как "федерация модулей" на китайский язык, а в официальной документации webpack на самом деле не приводится его истинное значение, а дается мотивация использования этой функции, то есть мотивация. Первоначальный текст выглядит следующим образом
Multiple separate builds should form a single application. These separate builds should not have dependencies between each other, so they can be developed and deployed individually.
This is often known as Micro-Frontends, but is not limited to that.
перевести на китайский
多个独立的构建可以形成一个应用程序。这些独立的构建不会相互依赖,因此可以单独开发和部署它们。
这通常被称为微前端,但并不仅限于此。
Объединив вышеизложенное, несложно понять, что на самом деле mf хочет объединить несколько приложений, развертываемых независимо друг от друга без взаимозависимости, в одно. С точки зрения непрофессионала, mf предоставляет возможность удаленно загружать приложения на других серверах в текущем приложении. В связи с этим можно выделить следующие два понятия:
- хост: приложения, которые ссылаются на другие приложения
- удаленный: приложения, используемые другими приложениями
Учитывая возможности mf, мы можем полностью реализоватьдецентрализациягруппа развертывания приложений: каждое приложение развертывается на своем собственном сервере, каждое приложение может ссылаться на другие приложения, а также на него могут ссылаться другие приложения, то есть каждое приложение может играть роль хоста или отображаться как удаленное, нет. центральное приложение.
2. Как использовать
Пример конфигурации:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
// 其他webpack配置...
plugins: [
new ModuleFederationPlugin({
name: 'empBase',
library: { type: 'var', name: 'empBase' },
filename: 'emp.js',
remotes: {
app_two: "app_two_remote",
app_three: "app_three_remote"
},
exposes: {
'./Component1': 'src/components/Component1',
'./Component2': 'src/components/Component2',
},
shared: ["react", "react-dom","react-router-dom"]
})
]
}
Благодаря приведенной выше конфигурации у нас есть предварительное представление о mf, то есть, если мы хотим использовать mf, нам нужно настроить несколько важных свойств:
имя поля | Типы | имея в виду |
---|---|---|
name | string | Требуемое значение, то есть имя модуля вывода, при удаленном обращении к нему путь${name}/${expose}
|
library | object | Способ объявления глобальных переменных, имя - имя umd |
filename | string | Имя файла вывода сборки |
remotes | object | Сопоставление имен удаленных приложений и их псевдонимов с использованием значения ключа в качестве имени. |
exposes | object | Пути ресурсов и их псевдонимы, которые могут быть раскрыты при удаленном обращении |
shared | object | Сторонние зависимости, которыми можно поделиться с другими приложениями, чтобы вашему коду не приходилось повторно загружать одни и те же зависимости. |
3. Принцип строительного анализа
Посмотрим код после сборки:
var moduleMap = {
"./components/Comonpnent1": function() {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_react_react"), __webpack_require__.e("src_components_Close_index_tsx")]).then(function() { return function() { return (__webpack_require__(16499)); }; });
},
};
var get = function(module, getScope) {
__webpack_require__.R = getScope;
getScope = (
__webpack_require__.o(moduleMap, module)
? moduleMap[module]()
: Promise.resolve().then(function() {
throw new Error('Module "' + module + '" does not exist in container.');
})
);
__webpack_require__.R = undefined;
return getScope;
};
var init = function(shareScope, initScope) {
if (!__webpack_require__.S) return;
var oldScope = __webpack_require__.S["default"];
var name = "default"
if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");
__webpack_require__.S[name] = shareScope;
return __webpack_require__.I(name, initScope);
}
Видно, что код включает в себя три части:
- moduleMap: Коллекция модулей, сгенерированных экспозицией.
- get: host С помощью этой функции вы можете получить компоненты в удаленном
- init: хост внедряет зависимости в удаленный через эту функцию
посмотри сноваmoduleMap
, прежде чем вернуться к соответствующему компоненту, передать__webpack_require__.e
Его соответствующие зависимости загружаются, посмотрим__webpack_require__.e
Что вы наделали:
__webpack_require__.f = {};
// This file contains only the entry chunk.
// The chunk loading function for additional chunks
__webpack_require__.e = function(chunkId) {
// 获取__webpack_require__.f中的依赖
return Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {
__webpack_require__.f[key](chunkId, promises);
return promises;
}, []));
};
__webpack_require__.f.consumes = function(chunkId, promises) {
// 通过__webpack_require__.o检查当前需要加载的chunk是否是在配置项中被声明为shared共享资源,如果能找到对应资源,则直接使用,不再去请求资源
if(__webpack_require__.o(chunkMapping, chunkId)) {
chunkMapping[chunkId].forEach(function(id) {
if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);
var onFactory = function(factory) {
installedModules[id] = 0;
__webpack_modules__[id] = function(module) {
delete __webpack_module_cache__[id];
module.exports = factory();
}
};
try {
var promise = moduleToHandlerMapping[id]();
if(promise.then) {
promises.push(installedModules[id] = promise.then(onFactory).catch(onError));
} else onFactory(promise);
} catch(e) { onError(e); }
});
}
}
Прочитав код ядра, можно сделать следующие выводы:
- Во-первых, mf заставит веб-пакет начинаться с
filename
Создать файл как имя файла - Во-вторых, файл с именем var отображается в файле
name
глобальная переменная, содержащаяexposes
так же какshared
Контент, настроенный в - Наконец, как
host
, первый проходremote
изinit
метод будет сам по себеshared
записыватьremote
, затем пройтиget
Получатьremote
серединаexpose
компоненты, в то время какremote
когда, судитьhost
Доступны ли общие зависимости, и если да, загрузите их.host
Эта часть зависимостей, если нет, загружает свои собственные зависимости.
4. Сценарии применения
Герои тоже боятся бесполезных мест, посмотрим, какие есть сценарии применения mf:
- микро интерфейс: Несколько приложений могут быть введены через общий доступ, и одно и то же приложение управляется бизнес-подразделениями. YY веб-интерфейс, набор независимой группы исследований и разработок.Микро интерфейсное решение EMPОн основан на возможностях mf.
- Повторное использование ресурсов для уменьшения объема компиляции: Общие компоненты, используемые несколькими приложениями, могут быть развернуты отдельно и введены в другие проекты во время выполнения с помощью функции mf, так что код компонента не будет компилироваться в проект, а также может удовлетворить потребности нескольких проектов одновременно. в то же время, убить двух зайцев одним выстрелом.
5. Наконец
В настоящее время толькоМикро интерфейсное решение EMPЭто набор, основанный на Module Federation сзрелые лесаа такжеПолная экологияМикроинтерфейсное решение80% крупных проектов, благодаря этой статье мы также можем понять, что решение микроинтерфейса EMP перспективно, масштабируемо и надежно. противМикро интерфейсное решение EMPобучения, с полнымвики-учебный каталогДля справки:
-
Базовый анализ знаний
Сравнение различных микроинтерфейсных решений
-
Быстрый старт
Как использовать и получить доступ к EMP в реактивном проекте
-
Расширенный учебник
Как проекты Vue и React звонят друг другу удаленно