一.什么是micro-app

微前端的概念是由ThoughtWorks在2016年提出的,它借鉴了微服务的架构理念,核心在于将一个庞大的前端应用拆分成多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用融合为一个完整的应用,或者将原本运行已久、没有关联的几个应用融合为一个应用。微前端既可以将多个项目融合为一,又可以减少项目之间的耦合,提升项目扩展性,相比一整块的前端仓库,微前端架构下的前端仓库倾向于更小更灵活。

它主要解决了两个问题:

  • 1、随着项目迭代应用越来越庞大,难以维护。
  • 2、跨团队或跨部门协作开发项目导致效率低下的问题。

二.基座访问子应用流程

二.子应用前端开发完成后,设置跨域支持

vue.config.js中添加配置

devServer: {
  headers: {
    'Access-Control-Allow-Origin': '*',
  }
}

三.子应用挂载到基座遇到的问题(前端vue3  webpack构建工具):

1.报错为跨域问题

解决方案: 

1)首先看一下部署后负载均衡(前端)是否可以访问,如果不可访问

2)在使用k8s中创建的前端应用的PodIP地址+端口号是否可以访问(注意:PodIP是实时更新地址,端口号是固定的; 如果PodIP+端口号正常 可以访问,那就点击强制同步DLB按钮同步PodIP与k8s创建的前端应用映射;如果还不可访问,找一下维护基座的人员,是否出现问题

2.前端应用正常访问后,挂载到基座时报错 405 Not Allowed

问题:基座与子应用配置不一致

解决方案:

1)需要和基座人员协商一直挂载的访问接口前缀,我们是使用:子应用名字(如果不是按照协商一直名字规则)+api ,就会报上图错误

2)一个子应用对应一个开发环境配置

提供给基座配置人员:

{
    name: 'projectname',
    url: 'http://10.80.244.32:30000',
    proxy: {
      api: 'http://10.83.240.49:18000',
    }
  },

前端开发环境配置:vue.config.js

module.exports = {
  lintOnsave: false,
  publicPath: './',
  devServer: {
    devServer: {
      headers: {
        'Access-Control-Allow-Origin': '*',
      },
      proxy: {
        '/projectname-api':{//注意前缀和提供给基座人员的name是一致的,否则报405 not allowed
          target:"http://10.83.240.49:18000",
          changeOrigin:true,
          sucure:false,
          pathrewrite:{
            "^/projectname-api":"/"
          }
        }
      }
    }
  }
}

nginx配置:

 server {
    listen 8888; # 监听端口
    server_name localhost; # 域名可以有多个,用空格隔开
    client_max_body_size 100m;
    proxy_send_timeout 300s;# 设置发送超时时间
    proxy_read_timeout 300s;

    location / {
      gzip on;
        gzip_min_length 1k;
        gzip_buffers    4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 9;
        gzip_types      text/plain application/x-javascript  text/css application/xml text/javascript application/x-httpd-php application/javascript application/json
        gzip_disable "MSIE [1-6]\.";
        gzip_vary on;

        root /user/share/nginx/html;    
        index index.html index.htm; #目录内的默认打开文件,如果没有匹配到index.html,则搜索index.htm,依次类推
        try_files $uri $uri/ /index.html;
        add_header "Access-Control-Allow-Origin" *;
        add_header "Access-Control-Allow-Methods" *;
        add_header "Access-Control-Allow-Headers" *;

        if($request_method="OPTIONS"){
           return 204
        }
    }

    #ssl配置省略
    location /api {
      # rewrite ^.+api/?(.*)$ /$1 break;
      proxy_pass http://10.83.240.49:18000; #node api server 即需要代理的IP地址
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-Forwarded-For $proxy_add_x_forwarded_for;
    }
    #error_page  404              /404.html;    #对错误页面404.html 做了定向配置

    # redirect server error pages to the static page /50x.html
    #将服务器错误页面重定向到静态页面/50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }

3.如果报错 404 

问题:基座与子应用配置不一致

 提供给基座配置人员信息

    name: 'projectname',
    url: 'http://10.80.244.32:30000',
    proxy: {
      weifuwu1: 'http://10.83.240.49:18000/weifuwu1',
      weifuwu2: 'http://10.83.240.49:18000/weifuwu2',
    }
  },

前端开发环境配置:vue.config.js

module.exports = {
  lintOnsave: false,
  publicPath: './',
  devServer: {
    devServer: {
      headers: {
        'Access-Control-Allow-Origin': '*',
      },
      proxy: {
        '/projectname-weifuwu1':{//注意前缀和提供给基座人员的name+微服务名称是一致的,
          target:"http://10.83.240.49:18000/weifuwu1",
          changeOrigin:true,
          sucure:false,
          pathrewrite:{
            "^projectname-weifuwu1":"/"
          }
        },
        '/projectname-weifuwu2':{
          target:"http://10.83.240.49:18000/weifuwu2",
          changeOrigin:true,
          sucure:false,
          pathrewrite:{
            "^projectname-weifuwu2":"/"
          }
        }
      },      
    }
  }
}

nginx配置:

 server {
    listen 8888; # 监听端口
    server_name localhost; # 域名可以有多个,用空格隔开
    client_max_body_size 100m;
    proxy_send_timeout 300s;# 设置发送超时时间
    proxy_read_timeout 300s;

    location / {
      gzip on;
        gzip_min_length 1k;
        gzip_buffers    4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 9;
        gzip_types      text/plain application/x-javascript  text/css application/xml text/javascript application/x-httpd-php application/javascript application/json
        gzip_disable "MSIE [1-6]\.";
        gzip_vary on;

        root /user/share/nginx/html;    
        index index.html index.htm; #目录内的默认打开文件,如果没有匹配到index.html,则搜索index.htm,依次类推
        try_files $uri $uri/ /index.html;
        add_header "Access-Control-Allow-Origin" *;
        add_header "Access-Control-Allow-Methods" *;
        add_header "Access-Control-Allow-Headers" *;

        if($request_method="OPTIONS"){
           return 204
        }
    }

    #ssl配置省略
    location ^~ /projectname-weifuwu1/ {
      # rewrite ^.+api/?(.*)$ /$1 break;
      proxy_pass http://10.83.240.49:18000/weifuwu1; #node api server 即需要代理的IP地址
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-Forwarded-For $proxy_add_x_forwarded_for;
    }

     location ^~ /projectname-weifuwu2/ {
      # rewrite ^.+api/?(.*)$ /$1 break;
      proxy_pass http://10.83.240.49:18000/weifuwu2; #node api server 即需要代理的IP地址
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-Forwarded-For $proxy_add_x_forwarded_for;
    }
    #error_page  404              /404.html;    #对错误页面404.html 做了定向配置

    # redirect server error pages to the static page /50x.html
    #将服务器错误页面重定向到静态页面/50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }

4.子应用获取基座用户信息 

1)在vuex中存储  store=>index.ts

import { defineStore } from "pinia";

interface MainState {
  count: number;
}

declare global {
  interface Window {
    microApp: any;
    __MICRO_APP_NAME__: string;
    __MICRO_APP_ENVIRONMENT__: string;
    __MICRO_APP_BASE_ROUTE__: string;
  }
}

export const useMain = defineStore("mainStore", {
  state: (): MainState => {
    return {
      count: 1,
    };
  },
  getters: {
    user() {
      if (window.__MICRO_APP_ENVIRONMENT__) {
        return window.microApp.getData().user;
      }
      return {};
    },
    curUserId(){
      if (window.__MICRO_APP_ENVIRONMENT__) {
        return window.microApp.getData().user;
      }
      return 0
    }
  },
  actions: {},
  },
});

获取vuex存储的基座用户信息  index.vue

import {useMain} from '../../store/index'
const store=useMain()


<template>
  <div>{{store.user}}</div>
</template>

2)在main.ts或者App.vue中获取:


if (window.__MICRO_APP_ENVIRONMENT__) {
  username=window.microApp.getData().user
  console.log(username)
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐