Как реализовать динамический импорт в 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 шт):

Автор решения: Alexander Lonberg

На первый взгляд все это кажется фантастическим. Но!!!

Ответ может быть найден в названии функции defineAsyncComponent(...).

Семантика имени define* предполагает, что возвращаемая переменная предварительно определенная константа, и в контексте динамического загрузчика, функция с таким именем применятся не должна!

Пример выше нарушает семантическую логику. И такого применения мы не найдем на странице справочника Vue.

Вернемся к вопросу: Vue вызывает функции в различных контекстах. А динамический загрузчик loadComponent() предположительно вызывается не в том контексте, который ожидает define*. Почему сработал первый вариант, неясно, если конечно он сработал вообще(в вопросе этого не ясно), но реализацию установки и загрузки компонентов следует пересмотреть.

→ Ссылка
Автор решения: Trottenheimer

Возможно решение является худшим из возможных, однако у меня заработало в случае, когда я обертываю в объект не путь для импорта, а саму функцию 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.

→ Ссылка