Вспомните практику микро-фронтенд-проекта qiankun!!!

внешний фреймворк

Введение

Я недавно работал над проектом микроинтерфейса, и я действительно наступил на много ям в процессе.Я пытался и делал ошибки в ограниченных данных, и я молчал и две строки слез ха-ха.Я буду запишите все ямы на этот раз, чтобы больше людей и меньше людей совершили обход, этот проект используетМуравей ФинансовыйКак фундамент как развитие.Нечего сказать, давайте поговорим!!!

Так что же такое цянькунь?

qiankun — это библиотека для реализации микроинтерфейса, основанная на single-spa, цель которой — помочь вам более легко и безболезненно создать готовую к производству систему архитектуры микроинтерфейса.

Что такое микрофронтенд

Архитектура микроинтерфейса имеет следующие основные ценности:

  • Независимость от стека технологий

    Основная структура не ограничивает технологический стек приложения доступа, а микроприложение имеет полную автономию.

  • Независимая разработка, независимое развертывание

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

  • Инкрементное обновление

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

  • При самостоятельном беге

    Изоляция между каждым микродатчиком, состояние не передается во время выполнения

Взято изофициальная документация qiankun

Основная конфигурация приложения

Основное приложение и подприложение этого проекта — vue,

скачать qiankun

npm install qiankun     

Зарегистрируйте микроприложение в основном приложении

// 导入乾坤函数
import {
  registerMicroApps,
  setDefaultMountApp,
  start
} from "qiankun";


Инкапсулировать метод рендеринга

Этот метод изначально вызывается один раз в main.js, в основном используется для монтирования основного приложения, а затем по очереди вызываются подприложения, поэтому судить претенциозно.Передаются параметры HTML и состояние загрузки подприложение соответственно.contentМы используем vuex для хранения полей для удобства использования


let app = null;

function render({ appContent, loading }) {
  if (!app) {
    app = new Vue({
      router,
      store,
      render: h => h(App),
    }).$mount('#app');
    
  } else {
    store.commit('microApp/changeCenter', appContent);
    store.commit('microApp/changeLoading', loading);
  }

}

Регистрация микроприложения

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

В параметрах **контейнер и рендер** зарегистрированного самоприложения есть множество ям для майнинга, о чем будет рассказано ниже.


function genActiveRule(routerPrefix) {
  return location => location.pathname.startsWith(routerPrefix);
}

//传递给子应用的数据
let msg = {
![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/4/27/171bbc5de042ec98~tplv-t2oaga2asx-image.image)
  data:'修炼爱情的辛酸,学会放好以前的渴望'
}

let apps = [
  {
    name: 'linjunjie', 
    entry: '//localhost:215',  // 改成自己子应用的端口号
    container:'#subView', //节点 id   //  沙盒模式 
    // render:render,  // 普通模式   
    activeRule: genActiveRule('/star'),
    props:msg
  }
]
   //注册的子应用 参数为数组
registerMicroApps(apps,{
  beforeLoad: [
    app => {
      console.log(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);
    },
  ],
});


setDefaultMountApp('/star/linjunjie')

//开启沙盒模式
start({ 
   sandbox :{strictStyleIsolation: true}
})

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

Элементы отображения, подготовленные основным приложением для подприложений


<template>
  <div id="app">
    <div id="nav">
      <!--//主应用 为子应用的跳转dom-->
      <div @click="onChangePage('/star/linjunjie')" >林俊杰</div>
      <div @click="onChangePage('/star/zhangyixin')" >张艺兴</div>
   
    </div>
<!--//用来展子应用的 内容区-->
     <div id="subView" class="sub-content-wrap" v-html="content"></div>
  </div>
</template>

<script>

  import { mapState } from 'vuex';
  export default{
    data(){
      return {
     
      }
    },
    computed:{
    //获取子应用HTML 数据
       ...mapState('microApp', ['content']),
       ...mapState('microApp', ['mircoAppLoading']),
    },

    methods:{
    
      //定义跳转方法
      onChangePage(url){
        console.log(url)
        
        this.routerGo(url, '我喜爱的男明星')
      },
  
      routerGo(href = '/', title = null, stateObj = {}) {
        window.history.pushState(stateObj, title, href); 
      },
    }
 }
</script>


Конфигурация вспомогательного приложения

Конфигурация подприложения относительно проста, дополнительная загрузка qiankun не требуется, а лайфхук можно экспортировать.

Жизненный крючок, который экспортирует ответ

экспортbootstrap,mount,unmountТри хука жизненного цикла для вызова основного приложения в нужное время.Обратите внимание, что при создании экземпляра маршрута считается, что при работе в среде qiankun маршрут должен иметь префикс, и префикс согласуется с параметрами в функции подприложения регистрации основного приложения genActiveRule("/subdemo")

Значение «звездочка» должно соответствовать значению основного приложения. Значение в genActiveRule("/star") должно быть согласовано и использоваться как основным приложением, так и микроприложением.

Если новый VueRouter не настроен в main.js, переместите эту конфигурацию в main.js для упрощения управления.

import routes from './router' //将路由信息导出方便使用 

let router = null;
let instance = null;

function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/star' : '/',  
    mode: 'history',
    routes,
  });

  instance = new Vue({
    router,
    store,
    render: h => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}

if (!window.__POWERED_BY_QIANKUN__) {
  render();
}else{
 __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}


export async function bootstrap() {
  console.log('[vue] vue app bootstraped');
}

export async function mount(props) {
 //props 包含主应用传递的参数  也包括为子应用 创建的节点信息
  console.log(props)
  render(props);
}

export async function unmount() {
  instance.$destroy();
  instance = null;
  router = null;
}

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

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

const packageName = require('./package.json').name;

module.exports = {
  output: {
    library: `${packageName}-[name]`,
    libraryTarget: 'umd',
    jsonpFunction: `webpackJsonp_${packageName}`,
  },
};

Решение по подзаявке

Создайте новый publicPath.js в подприложении и введите его в main.js

if (window.__POWERED_BY_QIANKUN__) { 
//处理资源
 __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; 
}

Решение проблем с загрузкой ресурсов

настроить vue.config.js

module.exports = {
  publicPath:`//localhost:${port}`,
}

vue.config.js полная конфигурация

const path = require('path');
const packageName = require('./package').name;

function resolve(dir) {
  return path.join(__dirname, dir);
}

const port = 7101; // dev port
module.exports = {

  publicPath:`//localhost:${port}`,
  outputDir: 'dist',
  assetsDir: 'static',
  filenameHashing: true,
 
  devServer: {
    // host: '0.0.0.0',
    hot: true,
    historyApiFallback: true,//添加 重点
    port,
    overlay: {
      warnings: false,
      errors: true,
    },
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },

  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src'),
      },
    },
    output: {
      library: `${packageName}-[name]`,
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${packageName}`,
    },
  },
};



Пит-рекорд

Если текущая страница является подприложением, обновите страницу 404.

Следующие методы настроены для основного приложения

  • Метод 1 Удалить элемент конфигурации в режиме

    mode: 'history', //   将此配置代码删除
    
  • Способ 2: настроить страницу 404

Если не закомментироватьmode: 'history'этот параметр Перенаправить страницу 404 на главную

{
    path: '*',
    name: 'indexNotFound',
    component: resolve => require(['@/components/home'], resolve),
    children: HomeChild,
},
Обнаружены проблемы с изоляцией в стиле подприложений при запуске режима песочницы
  • Основная конфигурация приложенияsandbox :{strictStyleIsolation: true}Режим рендеринга изменен с режима рендеринга на контейнерcontainer:'#subView', В это время установленный дом поддержания<div id="subView"> </div> Запомнить основной контейнер :#+id

  • Конфигурация вспомогательного приложения Основной перехват кода, упомянутый выше

    instance = new Vue({
      router,
      store,
      render: h => h(App),
    }).$mount(container ? container.querySelector('#app') : '#app'); //重点
    
    ``
    
    遇到的问题: 开启沙箱模式,如果是 采用 render 模式会报错 ,固选择container 模式
    
    
    
    

визуализация

Написал сюда, проект построен, посмотрим на эффект

Вот полный код для всех, чтобы узнатьАдрес кода на гитхабе

проблема проекта

  • Почему я не вижу эффекта суб-приложения после запуска проекта

    Измените номер порта субприложения, зарегистрированного в основном приложении main.js мастера, на номер порта вашего собственного проекта.

Эпилог

Есть и другие ямки в разработке.Забыл записать.Обязательно помните о кроссдоменной проблеме ресурсов подприложения развертывания проекта, которая требует Nginx для настройки кроссдоменных проблем.

Ученик начальных классов в мире фронтенда!!!