1年前端的脱发难题,如何同步修改更新后管脚手架代码

发布于 2022年 05月 03日 14:01

思考起因

公司后台管理项目越来越多,如何统一脚手架,如何同步更新升级脚手架代码?我身为菜鸡前端,不成熟开发规范技巧也导致这些问题越来越让人头疼

抛砖引玉

这里我整理了一下我的初步解决方案,希望大佬们看到不吝指教,给出更多更好的解决方案和思路。

使用微前端方案 qiankun

蚂蚁的微前端构架 qiankun

github地址:github.com/umijs/qiank…

参考项目

使用统一后台脚手架项目,比如ant design vue pro,在layout中创建创建 qiankunLayout,空白内容部分区域显示子程序。 参考项目:github.com/hql7/wl-mic… (感谢大神分享的项目)

看过参考项目后帮助我进一步了解了 qiankun(乾坤), 以下是参考项目内容

  • 微前端主应用与子应用如何构建
  • 主、子,各应用间动态通信(动态,各应用间实时监听,同步数据)
  • 主应用资源下发至子应用
  • 异步注册(主应用异步获取子应用注册表并将子应用对应的路由下发至子应用)
  • 异步路由(使用应用间通信,通知子应用路由数据,子应用在内部 addRoutes 异步插入路由)
  • 各应用间路由基础管理
  • 公共资源处理

脚手架中加入 qiankun

主程序 组件qiankunLayout初始化乾坤后 判断用户所属子程序并加载子程序, 之后给子程序传入主程序中的组件、通用工具、用户信息等供子程序使用。

<!-- basic-layout 中空白内容区域 -->
    <a-layout-content
        :style="{ height: '100%', margin: '24px 24px 0', paddingTop: fixedHeader ? '64px' : '0' }"
      >
        <multi-tab v-if="multiTab"></multi-tab>
        <transition v-if="!isSubApp" name="page-transition">
          <route-view />
        </transition>
        <div v-else>
          <!-- 子应用  -->
          <div v-if="loading">loading</div>
          <div id="subapp-viewport"></div>
          <div class="subapp-container" v-html="content" />
        </div>
      </a-layout-content>
<!-- qiankunLayout demo代码 -->
<template>
  <basic-layout :isSubApp="isSubApp" :loading="appLoading" :content="appContent" />
</template>

<script>
import {
  registerMicroApps,
  runAfterFirstMounted,
  setDefaultMountApp,
  start,
  initGlobalState
} from 'qiankun';
import { mapGetters } from 'vuex';
import BasicLayout from '@/layouts/BasicLayout';
import VueRender from "../VueRender";
const genActiveRule = routerPrefix => {
  return location => location.pathname.startsWith(routerPrefix);
};

export default {
  name: 'Overview',
  components: {
    BasicLayout
  },
  data() {
    return {
      VueRender,
      appLoading: false,
      appContent: ''
    };
  },
  computed: {
    ...mapGetters(['apps', 'isSubApp'])
  },
  created() {
    this.loadSubApp();
  },
  methods: {
    loadSubApp() {
      /**
       * Step1 初始化应用(可选)
       */
      this.VueRender({loading: true});
      /**
       * Step2 注册子应用
       */
      registerMicroApps(
        [
          {
            name: 'vue',
            entry: '//localhost:7101',
            // render: this.render,
            container: '#subapp-viewport',
            activeRule: genActiveRule('/vue')
          },
        ],
        {
          beforeLoad: [
            app => {
              console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
            }
          ],
          beforeMount: [
            app => {
              console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
            }
          ],
          afterUnmount: [
            app => {
              console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
            }
          ]
        }
      );

      const { onGlobalStateChange, setGlobalState } = initGlobalState({
        user: 'qiankun'
      });

      onGlobalStateChange((value, prev) =>
        console.log('[onGlobalStateChange - master]:', value, prev)
      );

      setGlobalState({
        ignore: 'master',
        user: {
          name: 'master'
        }
      });

      /**
       * Step3 设置默认进入的子应用
       */
      setDefaultMountApp('/vue');

      /**
       * Step4 启动应用
       */
      start({
        // sandbox: { strictStyleIsolation: true },
        // singular: false
      });

      runAfterFirstMounted(() => {
        console.log('[MainApp] first app mounted');
      });
    }
  }
};
</script>

主程序中包含权限管理 系统管理 路由生成等功能,不同项目的业务可以放到子程序中实现。实现主程序登录完成后根据不同用户载入子程序,这样主程序就可以统一进行代码管理。

结语

本文章只提供了一种简单的解决思路,具体项目中不同的项目会有不同的登录注册页面,不同的页面功能和风格都有待解决,具体实现代码等待后续文章中提供,希望有大佬能在留言板中给出更好的建议或者思路。

推荐文章