微前端 - 对外只开放一个端口

问题

按原来的微前端部署形式,需要对外开放N(子系统个数)+1(主应用)个端口,存在网络安全的问题。
注意:此处不考虑https的问题,如需考虑,参考http即可。

目标

  • 1、减少对外开放的端口
  • 2、保证子系统能独立更新部署和访问

方案

为了保证子系统仍然是独立的,那么每个子系统必定对应一个NGINX(一个端口),但是此端口可以考虑不对外部网络开放,通过主应用的NGINX进行内部跳转。

步骤

一、处理主应用

registerMicroApps(
  [
    {
      name: 'SubSystem',
      entry: '//IP:PORT',
      container: '#subContainer',
      activeRule: '/micro/sub-system'
    }
  ],
  {
  // 其实挂载子系统的速度很快,loading应该做到各个子系统中去。
  beforeLoad: (app) => { // 子应用加载前
    console.log('beforeLoad 子应用加载前')
  },
  afterMount: async (app) => { // 子应用完成加载后
    console.log('afterMount 子应用完成加载后')
  },
  beforeMount: (app) => {
    // 每次加载子系统都执行
  }
})

registerMicroApps(
  [
    {
      name: 'SubSystem',
      entry: '/micro-system/',
      container: '#subContainer',
      activeRule: '/micro/sub-system'
    }
  ],
  {
  // 其实挂载子系统的速度很快,loading应该做到各个子系统中去。
  beforeLoad: (app) => { // 子应用加载前
    console.log('beforeLoad 子应用加载前')
  },
  afterMount: async (app) => { // 子应用完成加载后
    console.log('afterMount 子应用完成加载后')
  },
  beforeMount: (app) => {
    // 每次加载子系统都执行
  }
})

将原本entry: '//IP:PORT',子系统入口跳转至子系统的IP和端口配置,改为entry: '/micro-system/',跳转至/micro-system/通过NGINX去拦截跳转内部服务器IP和端口。

二、处理子系统

  • 通过主应用访问子应用,加载子应用js资源
  • http://主应用IP:主应用端口/micro-system/js/chunk-vendors.********.js
  • 通过NGINX去拦截跳转内部子应用服务器IP和端口
  • http://子应用IP:子应用端口/micro-system/js/chunk-vendors.********.js

如果子应用不做任何改动,是访问不到资源的。

方案1,行不通

将子应用拦截/micro-system/在转发重写URL时去掉,然而测试现象是加载冲突,无法正确转发加载到资源。
请添加图片描述
通过F12查看,资源好像是访问到9000(主应用端口)下的了。

方案2,可行

在不重写去掉/micro-system/的前提下,资源能正常访问,则需给子系统所有资源路径加上前缀。

2.1、vue.config.js打包配置文件

追加publicPath属性:

publicPath: '/micro-system/',

该配置的意思是,子系统打包后的所有资源路径前缀加上/micro-system/。

2.2、qiankun的子应用配置文件

export const render = (props = {}) => {
  const { container } = props
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/micro/sub-system/' : '/',
    mode: 'history',
    routes
  })
  instance = new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')
}

export const render = (props = {}) => {
  const { container } = props
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/micro/sub-system/' : '/micro-system/',
    mode: 'history',
    routes
  })
  instance = new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')
}

在不是通过主应用访问时,即单独访问子系统时,为路由的base追加/micro-system/。
因为vue.config.js的配置,打包后的子系统资源前缀都加上了/micro-system/,此处访问资源也需要加上不然无法正确获取资源。

三、本地部署测试

3.1、主应用需要添加拦截跳转

proxy: {
  '/micro-system/': {
    target: 'http://localhost:9001/',
    changeOrigin: false,
    secure: false
  },

走主应用访问时资源,通过/micro-system/拦截,跳转子系统部署的IP和端口,此IP和端口可以不对外网开放。
可参考后台接口请求的拦截跳转。
资源加载:
请添加图片描述
加载效果:
请添加图片描述

3.2、子系统无需修改

但需要注意的是,访问的时候必须在端口后追加/micro-system/。
请添加图片描述

  • 原来访问地址:
  • http://localhost:9001/login
  • 现在访问地址:
  • http://localhost:9000/micro-system/login(通过主应用端口访问子系统)
  • http://localhost:9001/micro-system/login(直接访问子系统)

此时,你会发现所有的资源访问后面都多了/micro-system/。
请添加图片描述

四、服务器部署测试

4.1、主应用NGINX追加子系统拦截

location /micro-system/ {
  proxy_pass http://IP:PORT/micro-system/;
  proxy_set_header Host $host:$server_port;
}

走主应用访问时资源,通过/micro-system/拦截,跳转子系统部署的IP和端口,此IP和端口可以不对外网开放。
可参考后台接口请求的拦截跳转。
注意:原来的~*拦截(如果有的话)需要去掉,不然子系统的资源会被抢先拦截。

4.2、子系统NGINX拦截配置如下

location /micro-system/ {
    try_files $uri $uri/ /micro-system/index.html;
    alias /usr/share/nginx/html/;
    index index.html index.htm;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
  }

注意:

  • a)、原来的location / 拦截和~*拦截(如果有的话)可以去掉了,因为所有的资源都在/micro-system/下。
  • b)、本案例是通过docker容器管理NGINX的,在docker配置中,有将实际的dist包文件映射到/usr/share/nginx/html/。
- ./bpg-sub-system/web/dist:/usr/share/nginx/html

其实只需要将alias别名指向子系统dist包的位置即可。

结论

  • 如果子应用部署的服务器端口,提供对外访问:
    那么可以直接访问,只需要在端口后追加子系统拦截标识,即公共路径publicPath的配置即可。
  • 如果子应用部署的服务器端口,不对外提供访问:
    那么可以通过访问主应用的IP和端口,追加子系统拦截标识,同样可以通过NGINX转发的方式加载资源。
    (类比接口调用,通常后台接口的服务器是不开放对外直接访问的,需要通过NGINX转发。)
    此时,只需要对外提供主应用的端口,本案例是9000即可。
    当然了如果有HTTPS那就再加一个。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值