Как реализовать динамический импорт в Vue3 при использовании ModuleFederataion
Я подключил два приложения через ModuleFederation. Вроде как все работает нормально, все зависимости шарятся, однако работает это только если прописать функцию импорта примерно так:
const loadComponent = () => {
component.value = defineAsyncComponent(() => import(`app1/test`));
};
Я бы хотел иметь возможность использовать эту функцию для разных компонентов, то есть так:
const loadComponent = (path) => {
component.value = defineAsyncComponent(() => import(`app1/${path}`));
};
Однако, при использовании второго способа, возникает ошибка:
Module not found: Error: Can't resolve 'app1' in 'C:\Users\User\web\host\src'
Причем неважно, редактировать ли строку прямо в функции import, либо заранее прописать пусть через переменную:
const loadComponent = () => {
const path = 'app1/test'
component.value = defineAsyncComponent(() => import(path));
};
Этот вариант тоже не работает. Возникает предположение, что если в импорт не подать чистую строку, Vue ищет компонент в своей директории, а не в ModuleFederation.
Пожалуйста, подскажите, как можно исправить эту ошибку
Ответы (2 шт):
На первый взгляд все это кажется фантастическим. Но!!!
Ответ может быть найден в названии функции defineAsyncComponent(...)
.
Семантика имени define*
предполагает, что возвращаемая переменная предварительно определенная константа, и в контексте динамического загрузчика, функция с таким именем применятся не должна!
Пример выше нарушает семантическую логику. И такого применения мы не найдем на странице справочника Vue.
Вернемся к вопросу: Vue
вызывает функции в различных контекстах. А динамический загрузчик loadComponent()
предположительно вызывается не в том контексте, который ожидает define*
. Почему сработал первый вариант, неясно, если конечно он сработал вообще(в вопросе этого не ясно), но реализацию установки и загрузки компонентов следует пересмотреть.
Возможно решение является худшим из возможных, однако у меня заработало в случае, когда я обертываю в объект не путь для импорта, а саму функцию import с прописанным путем. Таким образом, для Vue3 решение будет примерно таким:
const componentList = ref([
{name: 'patientCard', importFunction: () => import('vaccination/patientCard')}
])
const loadComponent = async(importFunction) => {
component.value = defineAsyncComponent(() => importFunction());
};
loadComponent(componentList.value[0].importFunction)
По идее, поскольку мы обертываем импорт в функцию внутри объекта, импорт вернет промис только при обращении к самой функции importFunction.