Микро передняя часть приземлилась, и висящее сердце наконец отпустило

внешний интерфейс React.js
Микро передняя часть приземлилась, и висящее сердце наконец отпустило

«Эта статья участвовала в мероприятии Haowen Convocation Order, щелкните, чтобы просмотреть:Двойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!"

предисловие

Предлагаемая продуктом система должна быть модульной, а наше приложение должно быть построено с помощью различных комбинаций модулей. Разве это не популярный микро-фронтенд в последнее время?После некоторого общения с небольшими партнерами в группе он начал работать под давлением.После трех месяцев итеративной разработки, одновременно с развитием бизнеса, два модуля были перенесены на под-приложение. Система вышла в онлайн, и зависшее сердце окончательно упало.

Анализ состояния существующей системы

Существующая система является самостоятельным проектом, разработанным с использованием фреймворка umi, а основные бизнес-модули разделены по папкам. Публичные группы управляются через пакеты npm. Из-за длительного времени итерации системы необходимо решить несколько проблем, оставшихся в архитектуре.

  • 子应用采用ant4.x(Версия 3.x, используемая antd, сложнее обновить antd4.x, главным образом потому, что изменения формы относительно велики)
  • hooks替换redux部分state(В редуксстрое около сотни состояний, и в него же помещаются некоторые состояния, которые не стоит помещать в Редукс)
  • 统一封装requst(Разделен на независимые библиотеки запросов http и socket, поддерживает хуки)

Архитектура первой версии лендинга

image.png

Проблемы, которые необходимо решить путем внедрения микро-фронтендов

  • упаковка脚手架
  • Библиотека компонентов升级,служба поддержкиantd4.x
  • главное приложение通信
  • основное приложение共享Немного实例для использования вспомогательными приложениями
  • Магазин Redux получил部分数据необходимость共享, как ограничить
  • Подприложения поддерживают интернационализацию, интернационализированный контент动态加载
  • дополнительное приложение跳转родительское приложение
  • изоляция стиля

Ремонт официально начался

Фреймворк микро-интерфейса использует qiankun.Поскольку мы используем фреймворк umi, предоставляется соответствующий плагин @umijs/plugin-qiankun.

основное приложение

  1. Откройте конфигурацию qiankun в файле конфигурации umi.
  qiankun: {
    master: {},
  },
  1. Загрузить конфигурацию подприложения

function microApp(entryPrefix) {
  return [
    {
      name: 'app1', //唯一 id
      entry: entryPrefix ? `${entryPrefix}/app1` : '//localhost:3000',
    },
    {
      name: 'app2', //唯一 id
      entry: entryPrefix ? `${entryPrefix}/app2` : '//localhost:3001',
    },
    ... //其它子应用
  ];
}
export default microApp;
  1. Настройка активной маршрутизации подприложений
const router = [
  {
    path: '/main/app/rouer/app1', // (/main/app/rouer/)主应用部分路由
    microApp: 'app1',
    microAppProps: {
      autoSetLoading: true,
      className: 'appClassName',
      wrapperClassName: 'wrapperClass',

    },
  },
  {
    path: '/main/app/rouer/app2',
    microApp: 'app2',
    microAppProps: {
      autoSetLoading: true,
      className: 'appClassName',
      wrapperClassName: 'wrapperClass',

    },
  }
  ... //其它子应用
  ];

export default router;
  1. во входном файлеapp.jsЭкспорт объекта цянькунь
import microApp from './microApp';
import router from './router';

export const qiankun = new Promise((resolve) => {
  const entryPrefix = process.env.NODE_ENV === 'production' ? window.location.origin : null;
  const res = microApp(entryPrefix);
  resolve(res);
}).then(apps => {
  return {
    apps,
    routes: router,
  };
});

дополнительное приложение

  1. Откройте конфигурацию qiankun в umi
  qiankun: {
    slave: {},
  },
  1. во входном файлеapp.jsЭкспорт жизненного цикла qiankun

export const qiankun = {
    // 应用加载之前
    async bootstrap(props) {
     init(props);
    },
    // 应用 render 之前触发
    async mount(props) {
    },
    // 应用卸载时触发
    async unmount(props) {
    },
};

Основанный на плагине qiankun, предоставленном qiankun и umi, он относительно удобен в использовании. Давайте посмотрим, как решить вышеуказанную проблему.

Решите некоторые актуальные проблемы, с которыми столкнулись

Обновление библиотеки компонентов, поддержка antd4.x

Мы используем渐进式рефакторинг, нам нужен增量升级Возможность сначала сделать старый и новый код гармоничным共存, а затем постепенно преобразовывать старый код, пока не будет завершен весь рефакторинг. В настоящее время мы базируемся наantd3.xверсия библиотеки компонентов升级到4.x. Две версии обновляются в течение определенного периода времени одновременно, и эти две версии могут共存, перенесенное подприложение используетantd 4.x, чтобы гарантировать, что новые функции, которые мы можем использовать

Связь мастер-субприложение

umi qiankun pluginОбеспечивает способ взаимодействия главного и дочернего приложений.

Экспорт в основной портал приложенияuseQiankunStateForSlaveметод

export function useQiankunStateForSlave() {
  const [masterState, setMasterState] = useState({});

  return {
    SlaveSDK,
    getStore,
    // masterState,
    setMasterState,
  };
}
В подприложении автоматически генерируется глобальная модель, а значение реквизита, прозрачно передаваемое основным приложением, может быть получено в любом компоненте.
import { useModel } from 'umi';

function MyPage() {
  const masterProps = useModel('@@qiankunStateFromMaster');
  return <div>{JSON.stringify(masterProps)}</div>;
}

Проблем с общением между основным и подприложениями таким образом нет, а использовать вложенные многоуровневые подприложения не очень удобно, позже мы его трансформируем.

Основное приложение разделяет некоторые экземпляры для использования подприложениями.

В архитектуре микроинтерфейса не рекомендуется совместно использовать экземпляры приложений, потому что добиться независимой разработки, независимого развертывания будет сложно, а приложения будут связаны. Однако, поскольку мы разделяем систему, некоторые общие функции, такие как просмотр журналов во всплывающем окне, предварительный просмотр данных и другие функции, будут сначала использовать функции родительского приложения, и их необходимо будет использовать совместно. Здесь мы инкапсулируем SDK для использования подприложениями. Позже, если вы захотите превратить эту часть в самостоятельную разработку и независимое развертывание. Мы можем реализовать соответствующий интерфейс и динамически внедрить его.

  • Определите метод журнала для совместного использования
class Log {
  show = (params) => 
      // 具体业务逻辑
  }

  showOther = (params) => {
      // 具体业务逻辑
  }
}

export default new Log();

  • Создано в основном приложенииSlaveSDKПример
import intl from 'utils/intl';
import { history } from 'umi';
import { getParams } from 'utils/util';
import Log from './log';

class SlaveSDK {
  constructor() {
    this.log = Log;
    this.intl = intl;
    this.router = {
      history, // 主应用的history对象
      getParams, // 获取主应用的参数
    };
    ... 其它实例共享
  }
}

export default new SlaveSDK();

  • Передается в подприложения через передачу данных
import SlaveSDK from './SlaveSDK';
export function useQiankunStateForSlave() {
  return {
    SlaveSDK,
  };
}
  • Субприложение получает SDK в жизненном цикле, инициализирует и сохраняет его.
export const qiankun = {
    // 应用加载之前
    async bootstrap(props) {
         props?.SlaveSDK && setSDK(props.SlaveSDK);
    },
};

Некоторыми данными в Redux Store необходимо делиться, как это ограничить

Для бизнеса субприложений может потребоваться Redux Store部分数据, но мы не можем разместить весь Магазин暴露给子应用, сделать некоторые ограничения при использовании приложения, здесь мы используем代理объект для реализации

    const allowGet = { auth: '', user: '' }; // 需要共享的key
    const state = getReduxStore();
    const proxy = new Proxy(state, {
      get(target, property) {
        if (property in allowGet) {
          return target[property];
        }
        return undefined;
      },
    });
    return proxy;
  };

Подприложения поддерживают интернационализацию и динамическую загрузку интернационализированного контента.

Проходим путь SDK, делясь инстансамиintl, чтобы загрузить интернационализацию при инициализации субприложения.

/**
 * 国际化初始化
 */
const intlInit = async () => {
  // load语言 文件
  const result = await import('./locales');
  const intl = await import('./utils/intl');
  try {
    moment.locale(intl?.default?.getIntlLang?.() || 'zh_CN');
    intl?.default?.load(result.default);
  } catch (error) {
    console.error('intl error', error);
  }
};

Дочернее приложение переходит к родительскому приложению

Перепрыгнуть маршрут родительского приложения в дочернее приложение также можно, поставив маршрутизатор родительского приложенияhistoryОбъект передан дочернему приложению

import { history } from 'umi';
class SlaveSDK {
  constructor() {
    this.router = {
      history, // 主应用的history对象
      getParams, // 获取主应用的参数
    };

  }
}

изоляция стиля

Приложение для разделения стилей, которое мы используем,cssModule, уникальный ключ генерируется автоматически при компиляции. Основная проблема связана с antd, потому что мы загрузили и antd3, и antd4, что привело к конфликту стилей. Я изменил префикс при компиляции antd4. Конфигурация выглядит следующим образом

import { ConfigProvider } from 'antd';

// 弹框的前缀配置
 ConfigProvider.config({
    prefixCls: 'my-ant',
 });

// 组件的配置
<ConfigProvider prefixCls="my-ant">
</ConfigProvider>

развертывать

Система развернута с nginx, который обрабатывается по разным путям на одном сервере. Конфигурация выглядит следующим образом

server {
  listen       8080;
  server_name  localhost;


  location / {
    root   html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }


  location /app1 {
    root   html;
    index  index.html index.htm;
    try_files $uri $uri/ /app1/index.html;
  }


  location /app2 {
    root   html;
    index  index.html index.htm;
    try_files $uri $uri/ /app2/index.html;
  }
}

считать

В настоящее время запущена первая версия микрофронтенда, а в следующей версии могут быть вложенные многоуровневые подприложения. Необходимо решить следующие вопросы

  • Изоляция ресурсов
  • Вложенные многоуровневые приложения совместно используют состояние
  • Федерация модулей Webpack5 и qiankun объединяются для изоляции ресурсов
  • Усовершенствования скаффолдинга по мере увеличения числа подприложений

заключительные замечания

В этой версии скаффолдинг завершил основные функции и может генерировать наши суб-приложения в соответствии с модулями. После более позднего усовершенствования могут быть созданы основное приложение и подприложения, которые будут использоваться совместно. Выше приведены некоторые из проблем, суммированных при посадке микро-интерфейса.Если есть какие-либо проблемы, пожалуйста, поправьте меня.

Ссылаться на

Если вы считаете, что эта статья хороша, вы можете также

1,как, чтобы больше людей могли увидеть этот контент

2,Подписывайтесь на меня, пусть будут долгосрочные отношения

3. Подпишитесь на официальный аккаунт »Фронтенду есть что сказать», в ней много оригинальных статей и средств разработки, приветствую ваше внимание, и читайте мои статьи как можно скорее