<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          微前端 從 0到 1搭建

          共 9534字,需瀏覽 20分鐘

           ·

          2022-04-08 05:33

          在這里插入圖片描述

          微前端

          微前端

          Single-SPA

          ?

          微服務是面向服務架構(gòu)(SOA)的一種變體,把應用程序設計成一系列松耦合的細粒度服務,并通過輕量級的通信協(xié)議組織起來 具體地,將應用構(gòu)建成一組小型服務。這些服務都能夠獨立部署、獨立擴展,每個服務都具有穩(wěn)固的模塊邊界,甚至允許使用不同的編程語言來編寫不同服務,也可以由不同的團隊來管理

          ?
          image-20220405155852230

          概念

          官網(wǎng) :

          2018年 Single-SPA誕生了, single-spa是一個用于前端微服務化的JavaScript前端解決方案 ?(本身沒有處理樣式隔離、js執(zhí)行隔離) ?實現(xiàn)了路由劫持和應用加載;

          Alibaba -

          springboot

          - sofaboot

          Single-SPA 搞了個入口 ?--> ?qiankun

          2019年 qiankun基于Single-SPA, 提供了更加開箱即用的 API ?(single-spa + sandbox + import-html-entry),它 做到了技術(shù)棧無關,并且接入簡單(有多簡單呢,像iframe一樣簡單)。

          總結(jié):子應用可以獨立構(gòu)建,運行時動態(tài)加載,主子應用完全解耦,并且技術(shù)棧無關,靠的是協(xié)議接入(這里提前強調(diào)一下:子應用必須導出 bootstrap、mount、unmount三個方法)。

          micro front ends single spot

          應用量龐大,

          實現(xiàn)上,關鍵問題在于:

          • 多個 Bundle 如何集成?

          • 子應用之間怎樣隔離影響?

          • 公共資源如何復用?

          • 子應用間怎樣通信?

          • 如何測試?

          • 當然,這種架構(gòu)模式并非百益而無一害,一些問題也隨之而來:

            • 導致依賴項冗余,增加用戶的流量負擔

            • 團隊自治程度的增加,可能會破壞協(xié)作

              「.....」

          簡單來講,微前端的理念類似于微服務:

          ?

          In short, micro frontends are all about slicing up big and scary things into smaller, more manageable pieces, and then being explicit about the dependencies between them.

          ?

          將龐大的整體拆成可控的小塊,并明確它們之間的依賴關系。關鍵優(yōu)勢在于:

          • 代碼庫更小,更內(nèi)聚、可維護性更高
          • 松耦合、自治的團隊可擴展性更好
          • 「漸進地升級、更新甚至重寫部分前端功能成為了可能」

          微前端

          微前端到底是什么?
          img
          微前端架構(gòu)實戰(zhàn)中-single-spa 篇
          微前端

          微前端就是將不同的功能按照不同的維度拆分成多個子應用。通過主應用來加載這些子應用。

          image-20220403073941748

          微前端的核心在于「拆」, 拆完后再「合」!

          今天來一塊聊聊微前端 技術(shù)

          img
          • 一門前端語言的基礎 Vue React

          SingleSpa 實戰(zhàn)

          • 構(gòu)建子應用

          首先創(chuàng)建一個vue子應用,并通過single-spa-vue來導出必要的生命周期:

          vue?create?spa-vue??
          npm?install?single-spa-vue??
          import?singleSpaVue?from?'single-spa-vue';
          const?appOptions?=?{
          ???el:?'#vue',
          ???router,
          ???render:?h?=>?h(App)
          }
          //?在非子應用中正常掛載應用
          if(!window.singleSpaNavigate){
          ?delete?appOptions.el;
          ?new?Vue(appOptions).$mount('#app');
          }
          const?vueLifeCycle?=?singleSpaVue({
          ???Vue,
          ???appOptions
          });
          //?子應用必須導出以下生命周期:bootstrap、mount、unmount
          export?const?bootstrap?=?vueLifeCycle.bootstrap;
          export?const?mount?=?vueLifeCycle.mount;
          export?const?unmount?=?vueLifeCycle.unmount;
          export?default?vueLifeCycle;
          const?router?=?new?VueRouter({
          ??mode:?'history',
          ??base:?'/vue',???//改變路徑配置
          ??routes
          })
          • 配置庫打包

            //vue.config.js
            module.exports?=?{
            ????configureWebpack:?{
            ????????output:?{
            ????????????library:?'singleVue',
            ????????????libraryTarget:?'umd'
            ????????},
            ????????devServer:{
            ????????????port:10000
            ????????}
            ????}
            }
          • 主應用搭建

          ?

          將子應用掛載到id="vue"標簽中

          ?
          import?Vue?from?'vue'
          import?App?from?'./App.vue'
          import?router?from?'./router'
          import?ElementUI?from?'element-ui';
          import?'element-ui/lib/theme-chalk/index.css';
          Vue.use(ElementUI);
          const?loadScript?=?async?(url)=>?{
          ??await?new?Promise((resolve,reject)=>{
          ????const?script?=?document.createElement('script');
          ????script.src?=?url;
          ????script.onload?=?resolve;
          ????script.onerror?=?reject;
          ????document.head.appendChild(script)
          ??});
          }
          import?{?registerApplication,?start?}?from?'single-spa';
          registerApplication(
          ????'singleVue',
          ????async?()=>{
          ????????//這里通過協(xié)議來加載指定文件
          ????????await?loadScript('http://localhost:10000/js/chunk-vendors.js');
          ????????await?loadScript('http://localhost:10000/js/app.js');
          ????????return?window.singleVue
          ????},
          ????location?=>?location.pathname.startsWith('/vue')
          )
          start();
          new?Vue({
          ??router,
          ??render:?h?=>?h(App)
          }).$mount('#app')
          ?
          • 動態(tài)設置子應用
          if(window.singleSpaNavigate){
          ??__webpack_public_path__?=?'http://localhost:10000/'
          }

          前置條件

          npm?install?-g?yarn
          yarn?init
          • 安裝 官方 React

          Create React App是FaceBook的React團隊官方出的一個構(gòu)建React單頁面應用的腳手架工具。它本身集成了Webpack,并配置了一系列內(nèi)置的loader和默認的npm的腳本,可以很輕松的實現(xiàn)零配置就可以快速開發(fā)React的應用。

          # 全局安裝
          npm install -g create-react-app
          # 構(gòu)建一個my-app的項目
          npx create-react-app my-app
          cd my-app

          # 啟動編譯當前的React項目,并自動打開 http://localhost:3000/
          npm start
          • 構(gòu)建 React項目

            • npm

              npm?init?react-app?my-app
            • Yarn

              #?yarn?create?is?available?in?Yarn?0.25+
              yarn?create?react-app?my-app

          使用 qiankun 微前端構(gòu)建

          官方文檔: https://qiankun.umijs.org/zh

          ?

          首先我們需要創(chuàng)建 3個 前端應用, 微前端 ,就是 代表 一個小型應用的獨立部署,獨立交互,需要 應用之間進行通信,這里我們使用qiankun來完成 微前端 應用

          ?
          • 創(chuàng)建 ?3 個 react app

            yarn?create?react-app?qiankun-base??--template?typescript
            yarn?create?react-app?qiankun-micro-app1??--template?typescript
            yarn?create?react-app?qiankun-micro-app2??--template?typescript
            • app2
            • app1
            • 基座
          • 在 react app 應用中 ?安裝 qiankun ?依賴

            $?yarn?add?qiankun??#?or?npm?i?qiankun?-S
          • 分別創(chuàng)建 .env 文件來指定 項目 運行的端口號

          PORT=3010
          PORT=3011
          PORT=3012
          image-20220405201705407

          在主應用中index.tsx ? 注冊子應用

          import React from 'react';
          import ReactDOM from 'react-dom';
          import './index.css';
          import App from './App';
          import reportWebVitals from './reportWebVitals';


          import { registerMicroApps, start } from 'qiankun';

          registerMicroApps([
          {
          name: 'react app one', // app name registered
          entry: '//localhost:3011',
          container: '#micro-app2',
          activeRule: '/micro-app2',
          props:{
          nickname: "全棧小劉",
          age:19
          }
          },
          {
          name: 'react app two', // app name registered
          entry: '//localhost:3012',
          container: '#micro-app1',
          activeRule: '/micro-app1',
          props:{
          nickname: "全棧小劉",
          age:18
          }
          },
          ]);

          start();

          ReactDOM.render(


          ,
          document.getElementById('root')
          );

          // If you want to start measuring performance in your app, pass a function
          // to log results (for example: reportWebVitals(console.log))
          // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
          reportWebVitals();

          ?

          :子應用加載進來 ,需要有主應用進行掛載,現(xiàn)在我們已經(jīng)將 子應用注冊在 了 主應用當中

          ?
          • name 應用名稱
          • entry ?端口號
          • container 掛載容器
          • activeRule 激活的規(guī)則
          • props: 父子屬性之間傳參

          api文檔 : https://qiankun.umijs.org/zh/api

          • 在 App.tsx 中創(chuàng)建掛載點
          import React from 'react';
          import logo from './logo.svg';
          import './App.css';

          function App() {
          return (

          );
          }

          export default App;

          「所有」應用中 添加 public-path.js 用于 加載靜態(tài) 資源


          if?(window.__POWERED_BY_QIANKUN__)?{
          ????__webpack_public_path__?=?window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
          ??}

          在子應用中 添加 webpack 重寫項

          • 添加
          yarn?add?react-app-rewired??-D
          • 「設置 子應用」啟動,在 scripts
          ??"scripts":?{
          ????"start":?"react-app-rewired?start",
          ????"build":?"react-scripts?build",
          ????"test":?"react-scripts?test",
          ????"eject":?"react-scripts?eject"
          ??},

          在webpack 中 進行 overrides 重寫,重寫的 目的是 允許跨域

          • config-overrides.js
          const?{?name?}?=?require('./package');

          module.exports?=?{
          ??webpack:?(config)?=>?{
          ????config.output.library?=?`${name}-[name]`;
          ????config.output.libraryTarget?=?'umd';
          ????//?config.output.jsonpFunction?=?`webpackJsonp_${name}`;
          ????config.output.globalObject?=?'window';

          ????return?config;
          ??},

          ??devServer:?(_)?=>?{
          ????const?config?=?_;

          ????config.headers?=?{
          ??????'Access-Control-Allow-Origin':?'*',
          ????};
          ????config.historyApiFallback?=?true;
          ????config.hot?=?false;
          ????config.watchContentBase?=?false;
          ????config.liveReload?=?false;

          ????return?config;
          ??},
          };

          在不同的子應用當中 去加載 tsx 生命周期

          app1 ?、app2 、 index.tsx

          import React from 'react';
          import ReactDOM from 'react-dom';
          import './index.css';
          import App from './App';
          import reportWebVitals from './reportWebVitals';

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

          // @ts-ignore
          export async function mount(props) {
          console.log(props)
          ReactDOM.render(
          ,
          props.container
          ? props.container.querySelector('#root')
          : document.getElementById('root'));
          }
          // @ts-ignore
          export async function update(props){
          console.log("update props",props)
          }

          // @ts-ignore
          export async function unmount(props) {
          ReactDOM.unmountComponentAtNode(
          props.container
          ? props.container.querySelector('#root')
          : document.getElementById('root'));
          }
          // @ts-ignore
          if (!window.__POWERED_BY_QIANKUN__) {
          ReactDOM.render(,document.getElementById("root"))
          }




          // If you want to start measuring performance in your app, pass a function
          // to log results (for example: reportWebVitals(console.log))
          // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
          reportWebVitals();

          在 index.tsx 引入 public-path.js 解決靜態(tài)資源

          import './public-path.js'

          在 主 應用 添加 訪問

          import React from 'react';
          import logo from './logo.svg';
          import './App.css';

          function App() {
          return (

          );
          }

          export default App;

          • 在 主 應用 index.tsx 中 傳遞 數(shù)據(jù)
           props:{

          nickname: "全棧小劉",

          age:19

          }


          • 在 子應用 ?周期中進行打印
          export async function mount(props) {
          console.log(props)
          ReactDOM.render(
          ,
          props.container
          ? props.container.querySelector('#root')
          : document.getElementById('root'));
          }
          image-20220402075342284
          • 在 主應用中 監(jiān)聽事件改變
          import { initGlobalState, MicroAppStateActions } from 'qiankun';

          const state ={
          nickname: "全棧小劉"
          }

          // 初始化

          const actions: MicroAppStateActions = initGlobalState(state);

          actions.onGlobalStateChange((state,prev)=>{
          console.log(state,prev)
          })
          // 2秒鐘后 改變
          setTimeout(()=>{
          actions.setGlobalState({...state,age:19})
          },2000)

          • 在子應用中 監(jiān)聽改變
          export async function mount(props) {


          console.log(props)
          // @ts-ignore

          props.onGlobalStateChange((state,prev)=>{
          console.log(state,prev)
          setTimeout(()=>{
          props.setGlobalState({ ...state, age:20 });
          },2000)

          })
          // @ts-ignore


          ReactDOM.render(
          ,
          props.container
          ? props.container.querySelector('#root')
          : document.getElementById('root'));
          }
          • 安裝 NPM SCRIPT 插件 ,分別 啟動 運行
          image-20220402073016755

          接入 Vue3

          ?

          通用 vue3

          ?
          • 安裝最新的腳手架
          npm?install?-g?@vue/cli
          • 創(chuàng)建 項目 ?es6 js 模塊
          vue?create?qiankun-vue-micro-app3
          • 添加typescript ,轉(zhuǎn)換 ts ? ?-Y
          • yes
          vue?add?typescript
          • 依次加入 public-path.js
          /*?eslint-disable?*/?
          if?(window.__POWERED_BY_QIANKUN__)?{
          ????__webpack_public_path__?=?window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
          ??}
          • 安裝 qiankun
          ?yarn?add?qiankun
          • 參考qiankun官網(wǎng)的示例main.js ,完成生命周期的鉤子函數(shù)

          • base 中 進行注冊 ?index.tsx

          • vue-config.js 設置啟動端口

          • vue-config.js

          /*?eslint-disable?*/?
          const?{?name?}?=?require('./package');

          module.exports?=?{
          ????devServer:{
          ???????port:?3013,
          ???????headers:{
          ????????'Access-Control-Allow-Origin':?'*',
          ???????}
          ????},
          ????configureWebpack:{
          ??????output:?{
          ????????library:?`${name}-[name]`,
          ????????libraryTarget:?'umd'
          ??????}
          ????}
          ??
          };

          微前端項目 實戰(zhàn)

          https://github.com/a1029563229/micro-front-template

          效果圖
          • Reference Document :
            • https://juejin.cn/post/6844903943873675271
            • https://zhuanlan.zhihu.com/p/96464401
            • https://single-spa.js.org/


          瀏覽 75
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  干屄| 伊人官网在线 | 日本黄色电影网站 | 先锋白领AV | 日韩AV一卡二卡 |