You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Webpack模块联邦:登录后加载微前端组件的方案问询

解决方案:延迟微前端 RemoteEntry 加载至登录后

核心思路

当前问题出在 Module Federation 的 remotes 配置中,Promise 会在主应用初始化时立即执行,导致 RemoteEntry 脚本提前加载。我们需要将 RemoteEntry 的加载逻辑与登录状态绑定,确保只有在拿到 Access Token 后才触发加载。


方案一:动态注册微前端(推荐,灵活性更高)

放弃在 Webpack 配置中提前声明 remotes,改为登录成功后手动注册微前端容器。

1. 修改 Webpack Module Federation 配置

new ModuleFederationPlugin({
  name: 'my-app',
  filename: 'remoteEntry.js',
  remotes: {}, // 清空预配置的 remotes
  shared: [require('./package.json').dependencies],
}),

2. 编写动态注册函数

// 动态加载并注册单个微前端
async function registerRemote(remoteName, remoteEntryUrl) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = remoteEntryUrl;
    script.type = 'text/javascript';

    script.onload = () => {
      // 初始化远程容器,同步共享依赖
      window[remoteName].init(__webpack_share_scopes__.default);
      resolve(window[remoteName]);
    };

    script.onerror = () => reject(new Error(`Failed to load ${remoteName} remote entry`));
    document.head.appendChild(script);
  });
}

// 登录成功后执行的逻辑
async function handlePostLogin() {
  // 假设已通过登录接口获取到 token 并存储
  const token = await yourLoginApi();
  localStorage.setItem('access_token', token);

  // 批量注册所有微前端
  await Promise.all([
    registerRemote('first_mfe', 'http://localhost:8000/remoteEntry.js'),
    registerRemote('second_mfe', 'http://localhost:8001/remoteEntry.js')
  ]);

  // 注册完成后跳转至主页面
  router.push('/main');
}

3. 路由配置中延迟加载微前端组件

通过路由守卫拦截未登录状态,且微前端组件仅在注册后才动态导入:

const routes = [
  { path: '/login', component: () => import('./views/Login.vue') },
  {
    path: '/first-mfe',
    component: async () => {
      // 确保远程容器已注册
      const remoteContainer = window.first_mfe;
      const { default: MfeComponent } = await remoteContainer.get('./App.vue');
      return MfeComponent;
    },
    beforeEnter: (to, from, next) => {
      // 路由守卫:未登录则跳转登录页
      if (!localStorage.getItem('access_token')) {
        next('/login');
      } else {
        next();
      }
    }
  }
];

方案二:修改原有 Promise 逻辑,等待登录事件

基于你现有的代码改造,让 Promise 等待登录成功信号后再加载 RemoteEntry。

1. 修改 getUrl 函数

const getUrl = (resolve) => {
  // 加载 RemoteEntry 脚本的核心逻辑
  const loadRemoteScript = () => {
    const script = document.createElement('script');
    script.src = 'http://localhost:8000/remoteEntry.js'; // 根据微前端名称动态调整
    script.type = 'text/javascript';

    script.onload = () => {
      const module = {
        get: (request) => window.first_mfe.get(request),
        init: (arg) => {
          try {
            return window.first_mfe.init(arg);
          } catch (e) {
            console.log('Auth has already been loaded');
          }
        },
      };
      resolve(module);
    };
    document.head.appendChild(script);
  };

  // 检查是否已登录
  if (localStorage.getItem('access_token')) {
    loadRemoteScript();
  } else {
    // 监听自定义登录成功事件
    window.addEventListener('login-success', loadRemoteScript, { once: true });
  }
};

2. 登录成功后触发事件

async function login() {
  const token = await yourLoginApi();
  localStorage.setItem('access_token', token);
  // 触发登录成功事件,通知加载 RemoteEntry
  window.dispatchEvent(new CustomEvent('login-success'));
}

内容的提问来源于stack exchange,提问作者golia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 10:57:25