Winstack project transformation


Background: Winstack project is composed of multiple projects, such as KV, WinStore, security center, storage, operation and maintenance, network, system modules. Kv project uses Angular technology, WinStore, security center uses VUE technology



Kv project is an old multi-page Angular project. If you want to transform the micro-application, it is relatively troublesome and requires many changes. Therefore, in view of the above problems. So I decided to load the IFrame KV project with the micro-application. For example, click the virtual Resources menu to load the app-vue-KV application first, and iframe will load the URL specified by KV path.



Don’t be prejudiced against iframe, it’s also a way of implementing a micro front end, and it works well if there are no pop-ups, no full screen, etc. Configure caching and CDN acceleration. If Intranet access is used, it will not be slow.

Iframe and Qiankun can coexist. It is good for jQuery multi-page application to use Iframe to access, which scheme should be used when and in what scene, and the specific situation will be analyzed.

There are two common problems facing microfront-end frameworks

Virtually all microfront-end frameworks face these two common problems. When you’ve solved these two big problems, your microfront-end framework is basically ready to run.

  • The first problem is the application loading and switching. Including routing processing, application loading processing and application entry selection.
  • The second problem is application isolation and communication. This is the problem once the application has been loaded, including JS isolation (that is, side effects isolation), style isolation, and communication between parent and child applications.


Application routing with WinStack routing system

First let’s look at the problem of applying routing. In a micro-front-end architecture, routing is often divided like this, which is also a relatively simple solution.

Our main application loaded the application app-vuE-KV and the application WinStore. For the main application, I have two routes /app-vue-kv/* and /winstore/*. Under the main application route A, I will load the application app-vue-KV, and under the other main application route B, I will load the application WinStore.

We need to click on the left menu of the main app to jump to the app, so when faced with this problem, go to the official website to find the answer, so don’t panic.



How do I load a microapplication in a routing page of the main application

Primary application route Settings

components.router.js

path:”/app-vue-kv”

  {
    path: "/app-vue-kv".component: Layout,
    name: "Compute".meta: {
      title: "Computing".id: "57064191-4fc8-47f7-afad-1b892397b2bd"
    },
    // redirect: "/compute/virtualizedResources",
    children: [{path: "virtualizedResources".component: () = >
          import(
            /* webpackChunkName: "virtualizedResources" */ "@/views/compute/VirtualizedResources.vue"
          ),
        name: "VirtualizedResources".meta: {
          title: "Cloud Resource Pool".icon: "virtualizedResources".id: "4d302dd0-f831-4c31-b140-183ce98aa670".needLogin: true.noCache: false}}},Copy the code

Index.router. js adds a * to the path when registering this route. Note: If this route has other child routes, you need to register another route using this component.

  // Load the microapplication in a routing page of the main application
  {
    path: "/app-vue-kv".name: "appVuekv".component: Layout,
    children: [{path: "*".component: () = > import(".. /views/Portal.vue"),
        name: "Home".meta: {
          title: "Overview".icon: "home".id: "00444".needLogin: true}}},Copy the code

The activeRule of the microapplication needs to include this route path for the main application

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

const microApps = [
  {
    name: "app-vue-kv".entry: isProd ? "/child/app-vue-kv/" : "//localhost:9528".activeRule: getActiveRule("#/app-vue-kv"),
    props: { data: { store } }
  }
];
Copy the code

inPortal.vueOf this componentmountedCycle callstartFunction, be careful not to call it again.

import { start } from 'qiankun';
export default {
  mounted() {
    if (!window.qiankunStarted) {
      window.qiankunStarted = true; start(); }}},Copy the code

How to configure the router in hash mode for app-vue-KV

const routes = [
  {
    path: "/app-vue-kv".name: "Home".component: Home,
    children: [
      // All other routes are written here
      {
        path: "virtualizedResources".name: "VirtualizedResources".component: () = >
          import(
            /* webpackChunkName: "virtualizedResources" */ ".. /views/VirtualizedResources.vue"}]}];Copy the code

If winStore is in hash mode, how to configure the router

  {
    path: "/winstore/resource".component: Layout,
    name: "Resource".meta: {
      title: "Resource Management".id: "fa1aa081-bc7d-4c0c-9daf-4ac497007813"
    },
    children: [{path: "storagePoolManagement".component: () = >
          import(
            /* webpackChunkName: "StoragePoolManagement" */
            "@/views/resource/StoragePoolManagement.vue"
          ),
        name: "StoragePoolManagement".meta: {
          title: "Storage Pool Management".icon: "storagePoolManagement".id: "f6bfd3a8-cc7c-4e17-9ab3-04e7fe69815c".needLogin: true.noCache: false}}},Copy the code

$router.push({name: “WinstoreLogDetail”});

Microapplication data requests cross-domain configuration

background

Currently there is a singleton application developed with vue2.6, and we hope to use qiankun to transform the application into a micro application structure. Here records the configuration of each application data request agent when using VUE for microapplication development.

Root └ ─ ─ child / # for all the application of micro folder | ├ ─ ─ app - vue - kv/app store # micro application - vue - kv folder | ├ ─ ─ app - vue login/app store # micro application - vue login folder | ├ ─ ─ securityCenter / # deposit micro application securityCenter folder | ├ ─ ─ winstore / # deposit micro application winstore folder └ ─ ─ the main / # main applicationCopy the code

The problem

We know that in general, we use VUE to develop singleton applications independently. We can configure {devServer: proxy} of vue.config.js to realize interface request proxy. In microapplication development, the situation is slightly different. Specific cases can be divided into the following:

  1. Base independent development agent
  2. Sub-application independent development agent
  3. The child application nested agents within the base

The problem is that it is normal for the base and child applications to develop request data independently when they configure proxy services independently. After the child application is loaded into the base, the child application’s data request will be 404.

Base agent

Base Version VUe2.6.12,

  devServer: {
    proxy: {
      "/api": {
        // This should be consistent with the API_PROXY_PREFIX value in /services/api.js
        / / target: "http://192.168.205.213:8080/",
        target: userDev.api,
        changeOrigin: true.// Whether to cross domains
        pathRewrite: {
          "^/api": ""
        },
        ws: false
      },
      "/websocket": {
        target: userDev.socket, // is the target variable
        changeOrigin: true.// Whether to cross domains
        ws: false.// ws: false resolves that SockJS has been sending this request frequently
        pathRewrite: {
          "^/websocket": "/websocket"}}}},Copy the code

Subapplication proxy

  devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*"
    },
    proxy: {
      "/api": {
        // This should be consistent with the API_PROXY_PREFIX value in /services/api.js
        / / target: "http://192.168.205.213:8080/",
        target: userDev.api,
        changeOrigin: true.// Whether to cross domains
        pathRewrite: {
          "^/api": ""
        },
        ws: false
      },
      "/websocket": {
        target: userDev.socket, // is the target variable
        changeOrigin: true.// Whether to cross domains
        ws: false.// ws: false resolves that SockJS has been sending this request frequently
        pathRewrite: {
          "^/websocket": "/websocket"}}}},Copy the code

Analysis of the

At first glance, the proxy configuration in this microapplication is no different from the singleton configuration. In fact, the proxy configuration is based on the vue.config.js configuration or Webpack proxy configuration. The reason why sub-applications can normally request data, no matter independently developed or loaded to the base. This is because the base and subapplication are configured with the same header /proxyApi and the requested service address is the same. Back to the problem, if the base and subapplication are configured independently, for example: request address when the subapplication is developed independently: /user When the subapplication is nested within the base, the address will change to: localhost: 9000/user can see that the request address has been changed, and the original /user address can be used as a proxy through WebPack Server when developing independently. In microservices, the /user address is diverted to the base’s local development service localhost:9000/user, which is not recognized by the development service. So we will synchronize the child application’s proxy header with the base, so that the application’s request will be forwarded through the base development service. The reason why we set the same proxy header instead of configuring the child proxy again on the base is also for convenience, following the convention rather than the configuration principle.

How to deploy

Website provides solutions: qiankun.umijs.org/zh/cookbook…

Option 1: Put microapplications in a folder with a special name (not the same name as microapplications) (recommended)

└ ─ ─ dist / # root folder (after packaged as follows) | ├ ─ ─ child / # for all the application of micro folder | ├ ─ ─ app - vue - kv/app store # micro application - vue - kv folder | ├ ─ ─ app - vue login / # Application for micro app - vue - login folder | ├ ─ ─ securityCenter / # deposit micro application securityCenter folder | ├ ─ ─ winstore folder / # for micro application winstore ├ ─ ─ Index.html # main application of the index. The HTML ├ ─ ─ CSS / # main application CSS folder ├ ─ ─ js / # main application of js folder └ ─ ─ common / # public file | ├ ─ ─ SRC / └ ─ ─ child / # Store all the application of micro folder | ├ ─ ─ app - vue - kv/app store # micro application - vue - kv folder | ├ ─ ─ app - vue login/app store # micro application - vue - login folder | ├ ─ ─ SecurityCenter / # deposit micro application securityCenter folder | ├ ─ ─ winstore / # deposit micro application winstore folder └ ─ ─ the main / # main applicationCopy the code

This is because main and sub-applications use hash mode. Therefore, there is no need to set route base main micro-app.js

import store from "./store";
import router from "./router";
const getActiveRule = hash= > location= > location.hash.startsWith(hash);

/** * Note that name should be the same as the name field in the package of the subproject, and the address after * activeRule should be the same as name. * This address does not change when accessing subprojects in either production or development environments, but the subproject's access address entry changes with the environment. * For example, the vue subproject address is //localhost:9530 in the development environment and /child/winstore/ */ in the production environment

const isProd = process.env.NODE_ENV === "production";

const microApps = [
  {
    name: "securityCenter".entry: isProd ? "/child/securityCenter/" : "//localhost:9531".activeRule: getActiveRule("#/securityCenter")}, {name: "winstore".entry: isProd ? "/child/winstore/" : "//localhost:9530".activeRule: getActiveRule("#/winstore"),
    props: { data: { store } }
  },
  {
    name: "app-vue-login".entry: isProd ? "/child/app-vue-login/" : "//localhost:9529".activeRule: getActiveRule("#/app-vue-login"),
    props: { data: { store, router } }
  },
  {
    name: "app-vue-kv".entry: isProd ? "/child/app-vue-kv/" : "//localhost:9528".activeRule: getActiveRule("#/app-vue-kv"),
    props: { data: { store } }
  }
];

// Handle component sharing
const commonComponents = {};

const apps = microApps.map(item= > {
  return {
    ...item,
    container: "#appContainer" // The div mounted by the child application
  };
});

export default apps;

Copy the code

Process.env.node_env === “production” distinguishes the development environment

  • For development, use the local development environment directly
  • If it is production, it needs to be packaged

Deploy master and micro applications to the same server (same IP and port)

In the root directory: first install dependencies:`npm install`And then to perform`npm run install-all`Dependencies are installed for all projects and executed last`npm run start-all`You can start all projects.`npm run build-all`You can pack everything`vue`The project,`jQuery`Projects do not need to be packaged.Copy the code

The child application vue.config.js sets the publicPath

module.exports = {
	publicPath: process.env.NODE_ENV === "production" ? "/child/winstore/" : "/",}Copy the code

Nginx back-end deployment configuration

server {
  listen       8080;
  server_name  localhost;

        location ""{ #alias /opt/winsphere/webapp; alias /opt/winsphere/web/dist; index index.html; } location /child/webapp { alias /opt/winsphere/webapp; index index.html; } location /child/app-vue-login { alias /opt/winsphere/web/dist/child/app-vue-login; index index.html; } location /child/app-vue-kv { alias /opt/winsphere/web/dist/child/app-vue-kv; index index.html; } location /child/securityCenter { alias /opt/winsphere/web/dist/child/securityCenter; index index.html; } location /child/winstore { alias /opt/winsphere/web/dist/child/winstore; index index.html; }}Copy the code

At the end

In the Winstack route jump problems, packaging problems, cross-domain problems, etc.. May not like vUE use so 6 oh, need to step on the pit, encounter these problems, can see the official website, github issues, really can not solve the problems, you can find teammates in nail nail to solve, developed down, these problems can be solved through these ways.