最近用micro-app成功落地了微前端,把整个踩坑的过程记录了下来。
整体发现基座 应用和子 应用使用不同的技术框架 和版本 对于整个适配过程的差别还是挺大的,尤其是当子应用为vite 且micro-app的版本为0.8 时,子应用需要适配vite 的代价是巨大的,不过官网出1.X 版本优化了这个情况,如果子应用为vite时,可以参考官方文档MicroApp-1.X版本。
最终我的项目里使用的还是MicroApp-0.8版本,以下是我基座应用和子应用的相关框架和版本信息

子应用切换路由时会重新回到当前路由
正常情况:子应用有两个路由页面,一个列表页 ,一个详情页,在列表页点击能够正常跳转路由到详情页

异常情况:子应用切换路由时会重新回到当前路由

在控制台打印日志发现,切换路由时,子应用会卸载后重新加载

每次加载main.js时,会根据就基座传来的path进行路由的跳转,基座应用内嵌的是列表页,传来的path也是列表页的,因为跳转详情页会重新加载main.js,main.js会router.replace(列表页),所以导致了子应用切换路由时会重新回到当前路由的问题
            
            
              scss
              
              
            
          
          // main.js
function handleMicroData() {
  // 是否是微前端环境
  if (window.__MICRO_APP_ENVIRONMENT__) {
    // 主动获取基座下发的数据
    const microData = window.microApp.getData()
    if (microData.path) {
      router.replace({ path: microData.path, query: microData.query })  // 这里不能用router.push
    }
  }
}
        解决办法:
在基座关闭虚拟路由系统,或者改用0.8版本
当使用1.X版本会出现这个问题,1.X版本是默认开启虚拟路由系统的

关闭虚拟路由系统,这个问题可以解决
            
            
              ini
              
              
            
          
          <micro-app
  name="micro-app-manage"
  :url="microData.url"
  :data="microData"
  disable-memory-router  // 关闭虚拟路由系统
  @datachange="handleDataChange"
  @mounted="handleMount"
></micro-app>
        或者使用micro-app的0.8版本,也可解决这个问题
遗留问题 :暂时没找到micro-app使用1.X版本,且不关闭虚拟路由系统的情况下还不知道怎么解决这个问题,有大佬懂的话可以在评论区分享下
子应用返回上一页时(或者在浏览器回退),会无法切换回基座应用
解决办法:
- 1.X版本没有这个问题
 - 0.8版本有这个问题,需要在基座应用的beforeEach里加上这个逻辑
 
            
            
              javascript
              
              
            
          
          if (!window.history?.state?.current) {
   // 解决子应用是vue-router3 与 vue-router4冲突
   Object.assign(window.history.state, { current: from.fullPath });
}
        回退两次才能回到主应用页面
解决办法:
子应用的main.js里使用router.replace
            
            
              scss
              
              
            
          
          // main.js
function handleMicroData() {
  // 是否是微前端环境
  if (window.__MICRO_APP_ENVIRONMENT__) {
    // 主动获取基座下发的数据
    const microData = window.microApp.getData()
    if (microData.path) {
      router.replace({ path: microData.path, query: microData.query })  // 这里不能用router.push
    }
  }
}
        部署测试环境后,子应用接口无法正常请求
解决办法:
- 子应用
vue.config.js里publicPath要设置绝对路径 request请求封装里baseURL也要设置绝对路径
            
            
              js
              
              
            
          
          // vue.config.js
module.exports = {
  publicPath: process.env.NODE_ENV !== 'development' ? process.env.VUE_APP_WEB_URL : ''
  // 其他配置
}
        
            
            
              js
              
              
            
          
          // request.js
service.interceptors.request.use(
  async config => {
    config.baseURL = process.env.VUE_APP_WEB_URL + (config.baseUrl || process.env.VUE_APP_BASE_API) // url = base url + request url
    // 其他配置
    return config
  },
)
        子应用接口请求跨域
子应用请求的接口前提:接口要支持跨域(后端配置)
当后端接口支持跨域后,前端请求的方式就有两种:通过代理转发 和直接请求
代理转发:
1. 本地转发
本地的vue.config.js要配置跨域'Access-Control-Allow-Origin': '*'
            
            
              arduino
              
              
            
          
          devServer: {
    // 其他配置
    headers: {
      'Access-Control-Allow-Origin': '*'  // 允许跨域配置
    },
}
        2. 部署后转发
需要在nginx中配置跨域add_header Access-Control-Allow-Origin *;
            
            
              ini
              
              
            
          
          location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    gzip on;
    gzip_static on;
    add_header Cache-Control no-store;
    # 跨域配置
    add_header Access-Control-Allow-Origin *;
}
        直接请求
顾名思义就是不经过代理转发,直接发起请求了,也就不需要前面的vue.config.js和nginx的配置
跨域的其他问题:
我当时遇到了一个问题是,后端已经开启了跨域,但是前端还是有跨域问题,后来发现是前端里配置了withCredentials,相关内容原理可以参考这个【web前端】withCredentials有什么作用
总结:micro-app还是一个挺好上手的微前端框架,虽然遇到了不少坑(本人实力问题哈哈),好在社区也很活跃,很多问题都能在issues里找到答案,总之,推荐!
原创文章,记录成长,也希望对你有帮助!喜欢请点赞哦~
作者:前端小小梦
主页:了解更多,点击个人主页