qiankun微服务搭建遇到的坑

13 篇文章 2 订阅
6 篇文章 0 订阅

目录

1.子应用vue.config中的headers设置成可跨域请求

2.output设置成library,打包成umd库格式

3.父应用使用了babel-pollfill,子应用不要在在bable-pollfill

4.iconfont.js要取消样式隔离才能生效

5.关于nginx的配置

6.主应用和各应用相同依赖的版本号一定要一样,不然会有莫名其妙的BUG

7.项目中使用了三方插件时涉及跨域的问题

8.主应用、微应用部署在不同的服务器上,微应用更新后,浏览器读取缓存问题

9.主应用、微应用部署在不同服务器上,主应用读取不到微应用静态资源文件,读取的时主应用的静态资源文件

10.hash模式下无法激活子应用

11.微应用文件更新之后,访问的还是旧版文件

12.微应用打包之后 css 中的字体文件和图片加载 404

13.微应用 JSONP 跨域错误怎么处理?

14.如何解决拉取微应用 entry 时 cookie 未携带的问题


最近博主在开发一个微服务架构搭建的编程导航,方便大家学习交流。程序员导航是一个以Angular13.0,vue3.x, React16前端技术框架开发的一站式程序员学习工作娱乐导航网站,以让程序员更便捷为使命,始终围绕程序员需求,为程序员提供最新工具导航的便捷性服务网站!

下面说说本人在做qiankun微前端改造时遇到的一些坑,希望对大家有帮助。

1.子应用vue.config中的headers设置成可跨域请求

 headers: {
            //因为qiankun内部请求都是fetch来请求资源,所以子应用必须允许跨域
            "Access-Control-Allow-Origin": "*",
        },

2.output设置成library,打包成umd库格式

 configureWebpack: {
        output: {
            // 把子应用打包成 umd 库格式
            library: `${name}`,
            libraryTarget: 'umd',
            jsonpFunction: `webpackJsonp_${name}`,
        },
    }

3.父应用使用了babel-pollfill,子应用不要在在bable-pollfill

config.entry.app = [./src/main.ts]

4.iconfont.js要取消样式隔离才能生效

sandbox - boolean | { strictStyleIsolation?: boolean } - 可选,是否开启沙箱,默认为 true。

5.关于nginx的配置

# 主应用
location / {
    if ($request_uri ~* '/$|\.html$') {
        add_header Cache-Control no-store;
    }

    root /opt/pumpkin/fronted/;
    index index.html;
    try_files $uri $uri/ /index.html;
}
# cloud子应用
location /cloud/ { 
    if ($request_uri ~* '/$|\.html$') {
        add_header Cache-Control no-store;
    }
    alias /opt/pumpkin/fronted/;
    index index.html;
    try_files $uri $uri/ /index.html;
}
# mall子应用
location /mall/ {
    if ($request_uri ~* '/$|\.html$') {
        add_header Cache-Control no-store;
    }
    alias /opt/pumpkin/fronted/;
    index index.html;
    try_files $uri $uri/ /index.html;
}
# portal子应用
location /portal/ {
    if ($request_uri ~* '/$|\.html$') {
        add_header Cache-Control no-store;
    }
    alias /opt/pumpkin/fronted/;
    index index.html;
    try_files $uri $uri/ /index.html;
}

由于都是history的路由模式,所以:

每个应用配置都要加上try_files $uri $uri/ /index.html;否则会出现刷新报404错误
每个子应用都要单独配置location,否则在访问/cloud,/mall,/portal时刷新会报404

6.主应用和各应用相同依赖的版本号一定要一样,不然会有莫名其妙的BUG

7.项目中使用了三方插件时涉及跨域的问题

项目中使用了三方组件,会出现在子应用中无法使用的情况 ,在看源码时发现子应用的document.body中添加script标签失败没报错,但无法正确添加到body中,类似性质的问题还有美洽客服的引用,pdfjs的引用两种解决方法。


// 方脚本调用解决沙箱跨域问题
const opts: any = {
  prefetch: false,
  singular: true,
  fetch: window.fetch,
  excludeAssetFilter: (assetUrl: string) => {
    console.log("三方件扩展应用", assetUrl);
    if (
      assetUrl.includes("changyan") ||
      assetUrl.includes("zone.js") ||
      assetUrl.includes("kuaizhan")
    ) {
      return true;
    }
  },
};

start(opts);

8.主应用、微应用部署在不同的服务器上,微应用更新后,浏览器读取缓存问题

解决方案:服务器需要给微应用的配置一个响应头,意思就是每次请求都检查是否更新。

Nginx为例:

location = /index.html {
    add_header Cache-Control no-cache;
}

9.主应用、微应用部署在不同服务器上,主应用读取不到微应用静态资源文件,读取的时主应用的静态资源文件

module.exports = {
    output: {
        publicPath: `/app1/`,
    },
};

10.hash模式下无法激活子应用

const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);

11.微应用文件更新之后,访问的还是旧版文件

服务器需要给微应用的 index.html 配置一个响应头:Cache-Control no-cache,意思就是每次请求都检查是否更新。

以 Nginx 为例:

location = /index.html {
  add_header Cache-Control no-cache;
}

12.微应用打包之后 css 中的字体文件和图片加载 404

原因是 qiankun 将外链样式改成了内联样式,但是字体文件和背景图片的加载路径是相对路径。

而 css 文件一旦打包完成,就无法通过动态修改 publicPath 来修正其中的字体文件和背景图片的路径。

主要有以下几个解决方案:

所有图片等静态资源上传至 cdn,css 中直接引用 cdn 地址(推荐)

借助 webpack 的 url-loader 将字体文件和图片打包成 base64(适用于字体文件和图片体积小的项目)(推荐)

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|webp|woff2?|eot|ttf|otf)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {},
          },
        ],
      },
    ],
  },
};

vue-cli3 项目写法

module.exports = {
  chainWebpack: (config) => {
    config.module.rule('fonts').use('url-loader').loader('url-loader').options({}).end();
    config.module.rule('images').use('url-loader').loader('url-loader').options({}).end();
  },
}

13.微应用 JSONP 跨域错误怎么处理?

qiankun 会将微应用的动态 script 加载(例如 JSONP)转化为 fetch 请求,因此需要相应的后端服务支持跨域,否则会导致错误。

在单实例模式下,你可以使用 excludeAssetFilter 参数来放行这部分资源请求,但是注意,被该选项放行的资源会逃逸出沙箱,由此带来的副作用需要你自行处理。

若在多实例模式下使用 JSONP,单纯使用 excludeAssetFilter 并不能取得好的效果,因为各应用被沙箱所隔离;你可以在主应用提供统一的 JSONP 工具,微应用调用主应用提供的该工具来曲线救国。

14.如何解决拉取微应用 entry 时 cookie 未携带的问题

因为拉取微应用 entry 的请求都是跨域的,所以当你的微应用是依赖 cookie (如登陆鉴权)的情况下,你需要通过自定义 fetch 的方式,开启 fetch 的 cors 模式:

如果你是通过 registerMicroApps 加载微应用的,你需要在 start 方法里配置自定义 fetch,如:

import { start } from 'qiankun';

start({
  fetch(url, ...args) {
    // 给指定的微应用 entry 开启跨域请求
    if (url === 'http://app.alipay.com/entry.html') {
      return window.fetch(url, {
        ...args,
        mode: 'cors',
        credentials: 'include',
      });
    }

    return window.fetch(url, ...args);
  },
});

如果你是通过 loadMicroApp 加载微应用的,你需要在调用时配置自定义 fetch,如:

import { loadMicroApp } from 'qiankun';

loadMicroApp(app, {
  fetch(url, ...args) {
    // 给指定的微应用 entry 开启跨域请求
    if (url === 'http://app.alipay.com/entry.html') {
      return window.fetch(url, {
        ...args,
        mode: 'cors',
        credentials: 'include',
      });
    }

    return window.fetch(url, ...args);
  },
});

如果你是通过 umi plugin 来使用 qiankun 的,那么你只需要给对应的微应用开启 credentials 配置即可:

export default {
  qiankun: {
    master: {
      apps: [
        {
          name: 'app',
          entry: '//app.alipay.com/entry.html',
+         credentials: true,
        }
      ]
    }
  }
}

微服务体验连接:富朝阳的博客

欢迎在评论区交流。

如果文章对你有所帮助,❤️关注+点赞❤️鼓励一下博主会持续更新。。。。

我的博客原文:qiankun微服务搭建遇到的坑

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

富朝阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值