Micro-app micro-frontend base and mount configuration for sub-applications

1. What is a micro-app

The concept of micro-frontend was proposed by ThoughtWorks in 2016. It draws on the architectural concept of microservices. The core is to split a huge front-end application into multiple independent and flexible small applications. Each application can be independently developed and Run, deploy independently, and then integrate these small applications into a complete application, or integrate several unrelated applications that have been running for a long time into one application. Micro-frontends can not only integrate multiple projects into one, but also reduce the coupling between projects and improve project scalability. Compared with a whole front-end warehouse, the front-end warehouse under the micro-frontend architecture tends to be smaller and more flexible.

It mainly solves two problems:

  • 1. As the iterative application of the project becomes larger and larger, it is difficult to maintain.
  • 2. Cross-team or cross-department collaborative development projects lead to low efficiency.

2. Dock access sub-application process

2. After the front-end development of the sub-application is completed, set up cross-domain support

vue.config.jsAdd configuration in

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

3. Problems encountered when sub-applications are mounted to the base (front-end vue3 webpack build tool):

1. The error is reported as a cross-domain problem

solution: 

1) First check whether the load balancing (front end) is accessible after deployment, if not

2) Whether the PodIP address + port number of the front-end application created in k8s can be accessed (Note: PodIP is a real-time update address, and the port number is fixed; if the PodIP + port number is normally accessible, click the forced synchronization DLB button to synchronize The front-end application mapping created by PodIP and k8s; if it is still inaccessible, find the person who maintains the base to see if there is a problem

2. After the front-end application is accessed normally, an error 405 Not Allowed is reported when it is mounted to the base

Problem: Dock and sub-app configurations are inconsistent

solution:

1) It is necessary to negotiate with the base personnel for the prefix of the access interface that has been mounted. We use: sub-application name (if it is not in accordance with the negotiated name rule) + api, the above error will be reported

2) A sub-application corresponds to a development environment configuration

For base configurators:

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

Front-end development environment configuration: 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 configuration:

 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. If error 404 is reported 

Problem: Dock and sub-app configurations are inconsistent

 Information provided to base configurators

    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',
    }
  },

Front-end development environment configuration: 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 configuration:

 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. The sub-application obtains the base user information 

1) Store store=>index.ts in vuex

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: {},
  },
});

Get base user information stored by vuex index.vue

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


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

2) Obtain in main.ts or App.vue:


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

Guess you like

Origin blog.csdn.net/weixin_42901443/article/details/129914242