Проект микроинтерфейса Vue на основе single-spa

Vue.js

концепция

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

Микрофронтенды имеют смысл только в одностраничных приложениях, где интерфейс и сервер разделены. Ядром одностраничного приложения является вставка фрагмента html-кода, сгенерированного js, в определенное место в определенный момент. Проект микрофронтенда не меняет это ядро. Отличие микрофронтенд-проекта от монолитного заключается в том, что js-код, генерирующий html-фрагмент, может находиться под разными доменными именами, поэтому лучше не использовать относительные пути для путей каждого ресурса.

Проект микро-интерфейса состоит из нескольких подпроектов, поэтому необходимо объявить, из каких подпроектов состоит этот проект в проекте микро-интерфейса.Этот шаг называется регистрацией подпроекта. Что делает регистрация подпроекта: дайте проекту имя, укажите, когда проект загружается в html-документ и когда он выгружается из html-документа, поэтому он будет включать функцию ловушки жизненного цикла.

Схема структуры проекта

基于single-spa的vue微前端项目结构

адрес онлайн-доступа

адрес онлайн-доступа

исходный код демо

вопросы, требующие решения

  1. Регистрация подпроектов, асинхронная загрузка и управление жизненным циклом;
  2. Механизм обмена сообщениями между подпроектами и между ведущим и подчиненным;
  3. Меры изоляции безопасности между подпроектами;
  4. Структура и версия подпроекта независимы;
  5. Как управлять общими зависимыми библиотеками, бизнес-логикой (утилитами) и версиями между подпроектами и между главным и подчиненным;
  6. Способ самостоятельной отладки подпроектов и совместной отладки с основным приложением;
  7. выпускать

выполнить

Дополнение: используйте webpack для упаковки проекта

Регистрация функций жизненного цикла для каждого приложения

Дополнение: все подпроекты - это проекты vue.

Установить одиночный спа-вью

vue add single-spa

// 或者

npm install --save single-spa-vue

переписать входной файл

import vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store/base';
import singleSpaVue from 'single-spa-vue';
import elementUI from 'element-ui';
vue.use(elementUI)
vue.config.productionTip = false;
const vueLifecycles = singleSpaVue({
  Vue:vue,
  appOptions: {
    el:'#main',
    render: (h) => h(App),
    router,
    store
  },
});

export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;

вывести государственные ресурсы

настроитьwebpackПоле externals включаетwebpackПри упаковке не упаковывайте общедоступные библиотеки, такие как (vue, vue-router, частные пакеты npm и т. д.), как показано ниже:

{
    externals:['vue',{'vue-router':'vueRouter'},{'element-ui':'elementUI'}]
}

Установить формат упаковки проекта

output: {
    ...
    libraryTarget: 'umd',
    library: xxx,
}

Зарегистрировать подпроект

Конфигурация каждого подпроекта

{
        name:'main-project',
        base:true,
        projectIndex:'http://localhost:9100',
    },
    {
        name:'customers',
        base:false,
        path:'#/customers',
        domID:'main',
        projectIndex:'http://localhost:5100',
    },
    {
        name:'goods',
        base:false,
        path:'#/goods',
        domID:'main',
        projectIndex:'http://localhost:9010',
    }

@hydesign/grape

использовать@hydesign/grapeПолная регистрация подпроекта, асинхронная загрузка и управление жизненным циклом, а также структура и версия подпроекта независимы.@hydesign/grapeа такжеwebpackВнешние компоненты можно использовать вместе для извлечения библиотеки, которую вы не хотите упаковывать в проект, и динамически загружать библиотеку во время выполнения проекта.

 import Grape from '@hydesign/grape';

 new Grape(appsConf)
        .setImportMap({
                "vue": "https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js",
                "vueRouter": "https://cdn.jsdelivr.net/npm/vue-router@3.0.7/dist/vue-router.min.js",
                "elementUI":"https://cdn.jsdelivr.net/npm/element-ui@2.12.0/lib/index.js",
                "Vuex":"https://cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js",
                "axios":"https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js",
                "hytools":"https://cdn.jsdelivr.net/npm/hytools@1.2.0/dist/index.js"
            })
        .start()

Добавьте логотип в запись js подпроекта

проходить черезwebpackПосле упаковки проект может вставлять в index.html более одного js-скрипта, поэтому для обеспечения@hydesign/grapeМожет правильно проанализировать запись js из записи доступа к проекту и добавить настраиваемый атрибут в файл записи js.

const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
plugins:[
    ...
    new ScriptExtHtmlWebpackPlugin({
      custom: {
        test: /app.*\.js$/,
        attribute: 'entry',
        value: true
      }
    })
  ]

Настроить междоменный доступ

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

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

путь доступа к ресурсу

Поскольку доступ к ресурсам подпроекта осуществляется в проекте входа (проект входа и подпроект находятся в разных доменах), необходимо установить в publicPath подпроекта полный путь (то есть включая протокол и доменное имя) , чтобы обеспечить правильную загрузку ресурсов подпроекта.output.publicPath

Связь между приложениями

Используйте пользовательские события браузера для связи между приложениями

// customers
window.dispatchEvent(new CustomEvent('logout'));

// main-project
 window.addEventListener('logout',handler);

Примечание. Между приложениями должно быть как можно меньше связи. Если два приложения часто обмениваются данными, их следует объединить в одно.

Изолировать стили css

использоватьwebpack,postcssОхват всех CSS для бизнеса на этапе сборки

postcss:{
    plugins:[require('postcss-plugin-namespace')('.main-project',{ ignore: [ '*'] })]
}

Работать независимо

Используйте cross-env для установки переменных среды и получите доступ к значению переменной среды process.env.VUE_APP_SINGLERUN в файле записи js, чтобы определить, создавать ли новый корневой экземпляр vue.

Справочная статья