自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于 Qiankun 微前端實(shí)踐- 從零到一篇

開發(fā) 前端
微前端就是將不同的功能按照不同的維度拆分成多個子應(yīng)用。通過主應(yīng)用來加載這些子應(yīng)用。微前端的核心在于拆,拆完后再合!

簡短的概括:微前端痛點(diǎn)與解決問題

1?使用背景

1)在同一個頁面可以使用多個前端框架(React, AngularJS, Vue 等);

2)用新框架編寫新代碼,無需重寫已有的 app;

3)代碼的延遲加載可以縮減初次加載時(shí)長;

2?主要解決的問題:

1)在一個 app 中不同的模塊由不同的團(tuán)隊(duì)維護(hù),而每個團(tuán)隊(duì)所用的技術(shù)棧可能不同,而且發(fā)版周期不同。

2)所使用的前端框架升級負(fù)擔(dān),新版本可能存在不兼容的更新,升級后可能對已有的業(yè)務(wù)產(chǎn)生 bug,造成難以升級。限制了前端框架新版本的使用。

一、為什么需要微前端

「~ 微前端導(dǎo)圖 ~」

我們通過 3w (what,why,how) 的方式來講解微前端

1、what? 什么是微前端?

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

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

微前端架構(gòu)具備以下幾個核心價(jià)值:(重要)(摘自 qiankun官方文檔)

1)技術(shù)棧無關(guān)

主框架不限制接入應(yīng)用的技術(shù)棧,微應(yīng)用具備完全自主權(quán);

2)獨(dú)立開發(fā)、獨(dú)立部署

微應(yīng)用倉庫獨(dú)立,前后端可獨(dú)立開發(fā),部署完成后主框架自動完成同步更新;

3)增量升級

在面對各種復(fù)雜場景時(shí),我們通常很難對一個已經(jīng)存在的系統(tǒng)做全量的技術(shù)棧升級或重構(gòu),而微前端是一種非常好的實(shí)施漸進(jìn)式重構(gòu)的手段和策略;

4)獨(dú)立運(yùn)行時(shí)

每個微應(yīng)用之間狀態(tài)隔離,運(yùn)行時(shí)狀態(tài)不共享;

2、why? 為什么去使用他?

1)不同團(tuán)隊(duì)間開發(fā)同一個應(yīng)用技術(shù)棧不同怎么破?

2)希望每個團(tuán)隊(duì)都可以獨(dú)立開發(fā),獨(dú)立部署怎么破?

3)項(xiàng)目中還需要老的應(yīng)用代碼怎么破?

我們是不是可以將一個應(yīng)用劃分成若干個子應(yīng)用,將子應(yīng)用打包成一個個的lib。當(dāng)路徑切換時(shí)加載不同的子應(yīng)用。這樣每個子應(yīng)用都是獨(dú)立的,技術(shù)棧也不用做限制了!從而解決了前端協(xié)同開發(fā)問題。

3、How? 怎么落地微前端?

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

說明:single-spa 解決了以應(yīng)用為維度的路由,應(yīng)用的注冊,監(jiān)聽,最重要的是賦予了應(yīng)用生命周期和生命周期相關(guān)事件。

*Single-SPA 缺陷:不夠靈活,不能動態(tài)加載js文件;樣式不隔離,沒有js沙箱的機(jī)制。

2019年 qiankun 是微前端框架,提供了更加開箱即用的 API (single-spa + sandbox + import-html-entry),它基于 single-spa,具備 js 沙箱、樣式隔離、HTML Loader、預(yù)加載 等微前端系統(tǒng)所需的能力。qiakun 升級 2.0 后,支持多個微應(yīng)用的同時(shí)加載,有了這個特性,我們基本可以像接入 iframe 一樣方便的接入微應(yīng)用。

*總結(jié):子應(yīng)用可以獨(dú)立構(gòu)建,運(yùn)行時(shí)動態(tài)加載,主子應(yīng)用完全解耦,技術(shù)棧無關(guān),靠的是協(xié)議接入(子應(yīng)用必須導(dǎo)出 bootstrap,mount,unmount方法)

擴(kuò)展:

1)Single-SPA 官網(wǎng)地址:

https://zh-hans.single-spa.js.org/docs/getting-started-overview

2)qiankun官網(wǎng)地址:

https://qiankun.umijs.org/zh

二、解決隔離的方案

1、css 隔離方案

子應(yīng)用之間樣式隔離:

Dynamic Stylesheet 動態(tài)樣式表,當(dāng)應(yīng)用切換時(shí)移除老應(yīng)用樣式,添加新應(yīng)用樣式;

主應(yīng)用和子應(yīng)用之間的樣式隔離:

1)BEM(Block Element Modifier ) 約定項(xiàng)目前綴;

2)css-Modules 打包時(shí)生成不沖突的選擇器名;

3)Shadow DOM 真正意義上的隔離;

4)css-in-js

2、沙箱 shaowDom

*css 解決方法:

// domapi
// 外界無法訪問 shadow dom
let shadowDOM = document.getElementById('x').attachShadow({mode: 'closed'});
let pElm = document.createElement('p');
pElm.innerHTML = 'hello';
let styleElm = document.createElement('style');
styleElm.textContent = `
p{color: red}
`
shadowDOM.appendchild(styleElm);
shadowDOM.appendchild(pElm);

*JS 沙箱 proxy

快照沙箱簡單理解:1年前拍一張 在拍一張 (將區(qū)別保存起來) 在回到一年前

源碼實(shí)踐

let sandbox = new SnapshotSandbox();

class SnapshotSandbox{
constructor(){
this.proxy = window; // window屬性
this.modifyPropsmap = {}; // 記錄在window上的修改
this.active();
}
active() { // 激活
this.windowSnapshot = {}; //拍照
for(const prop in window) {
if(window.hasOwnProperty(prop)){
this.windowsnapshot[prop] = window[prop];
}
}
object.keys(this.modifyPropsMap).forEach(p=>{
window[p] = this.modifyPropsMap[p];
})
}

inactive(){ // 失活
for(const prop in window){
if(window.hasOwnProperty(prop)){
if(window[prop] !== this.windowsnapshot[prop]){
this.modifyPropsMap[prop] = window[prop];
window[prop] = this.windowsnapshot[prop]
}
}
}
}
}

// 應(yīng)用的運(yùn)行 從開始到結(jié)束, 切換后不會影響全局
((window)=> {
window.a = 1;
window.b = 2;
console.log(window.a,window.b);
sandbox.inactive();
console.log(window.a,window.b);
sandbox.active();
console.log(window.a,window.b);
})(sandbox.proxy); // sandbox.proxy 就是window
// 如果是多個子應(yīng)用就不能使用這種方式了,es6proxy
// 代理沙箱可以實(shí)現(xiàn)多應(yīng)用沙箱。把不同的應(yīng)用用不同的代理來處理

三、qiankun (乾坤) 項(xiàng)目實(shí)踐

*將普通的項(xiàng)目改造成 qiankun 主應(yīng)用基座,需要進(jìn)行三步操作:

1、創(chuàng)建微應(yīng)用容器 - 用于承載微應(yīng)用,渲染顯示微應(yīng)用

2、注冊微應(yīng)用 - 設(shè)置微應(yīng)用激活條件,微應(yīng)用地址等等;

3、啟動 qiankun;

擴(kuò)展:主應(yīng)用不限技術(shù)棧,只需要提供一個容器 DOM,然后注冊微應(yīng)用并 start 即可。

*微前端 qiankun 項(xiàng)目實(shí)踐:主應(yīng)用(基座)配置 react 17.0.2,子應(yīng)用配置 vue 2.6.10

詳細(xì)配置如下:

1. 主應(yīng)用(基座)配置 react 17.0.2

1.1 主應(yīng)用為子應(yīng)用準(zhǔn)備的 展示元素 (文件:src/App.js )

import {BrowserRouter as Router,Link} from 'react-router-dom'
function App() {
return (
<div className="App">
<Router>
<Link to="/vue">vue應(yīng)用</Link>
</Router>
{/* 切換導(dǎo)航, 將微應(yīng)用渲染container容器中 */}

<div id="container"></div>
</div>
);
}

export default App;

1.2 引入react 渲染,注冊 registerApps (文件:src/index.js )

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './registerApps'

ReactDOM.render(
<App />,
document.getElementById('root')
);

1.3 在主應(yīng)用中注冊微應(yīng)用(文件:src/registerApps.js)

1?安裝 qiankun (建議安裝:qiankun 2.X以上,支持多個微應(yīng)用的同時(shí)加載)

yarn add qiankun 或者 npm i qiankun

相關(guān)配置信息:

// ------ Step1 引入 qiankun
import { registerMicroApps, start } from 'qiankun'; // 底層是基于single-spa

// ----- Step2 注冊子應(yīng)用
registerMicroApps([{
name: 'm-vue',
entry: '//localhost:20000',
container: '#container',
activeRule: '/vue',
},
], {
beforeLoad: () => {
console.log('加載前')
},
beforeMount: () => {
console.log('掛在前')
},
afterMount: () => {
console.log('掛載后')
},
beforeUnmount: () => {
console.log('銷毀前')
},
afterUnmount: () => {
console.log('銷毀后')
},
})

// ----- Step3 啟動應(yīng)用
start();

2. 子應(yīng)用配置 vue 2.6.10

主應(yīng)用基座只有一個主頁,現(xiàn)在我們需要接入微應(yīng)用。

qiankun 內(nèi)部通過 import-entry-html 加載微應(yīng)用,要求微應(yīng)用需要導(dǎo)出生命周期鉤子函數(shù)(見下圖)。

從上圖可以看出,qiankun 內(nèi)部會校驗(yàn)微應(yīng)用的生命周期鉤子函數(shù),如果微應(yīng)用沒有導(dǎo)出這三個生命周期鉤子函數(shù),則微應(yīng)用會加載失敗。

如果我們使用了腳手架搭建微應(yīng)用的話,我們可以通過 webpack 配置在入口文件處導(dǎo)出這三個生命周期鉤子函數(shù)。如果沒有使用腳手架的話,也可以直接在微應(yīng)用的 window 上掛載這三個生命周期鉤子函數(shù)。

2.1 調(diào)整子應(yīng)用 main.js 文件:

import Vue from 'vue'
import App from './App.vue'
import router from './router'

// Vue.config.productionTip = false

let instance = null
function render(props) {
instance = new Vue({
router,
render: h => h(App)
}).$mount('#app'); // 這里是掛載到自己的html中 基座會拿到這個掛載后的html 將其插入進(jìn)去
}

if (window.__POWERED_BY_QIANKUN__) { // 動態(tài)添加publicPath
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
if (!window.__POWERED_BY_QIANKUN__) { // 默認(rèn)獨(dú)立運(yùn)行
render();
}

// 需要暴露接入?yún)f(xié)議
export async function bootstrap(props) {
console.log('[vue] vue app bootstraped');
};
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount(props) {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}

說明:導(dǎo)出相應(yīng)的生命周期鉤子函數(shù)。

微應(yīng)用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 導(dǎo)出 bootstrap、mount、unmount 三個生命周期鉤子,以供主應(yīng)用在適當(dāng)?shù)臅r(shí)機(jī)調(diào)用。

*擴(kuò)展資源:

/**
* bootstrap 只會在微應(yīng)用初始化的時(shí)候調(diào)用一次,下次微應(yīng)用重新進(jìn)入時(shí)會直接調(diào)用 mount 鉤子,不會再重復(fù)觸發(fā) bootstrap。
* 通常我們可以在這里做一些全局變量的初始化,比如不會在 unmount 階段被銷毀的應(yīng)用級別的緩存等。
*/
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}

/**
* (重要)應(yīng)用每次進(jìn)入都會調(diào)用 mount 方法,通常我們在這里觸發(fā)應(yīng)用的渲染方法
*/
export async function mount(props) {
console.log('[vue] props from main framework', props);
storeTest(props);
render(props);
}

/**
* 應(yīng)用每次 切出/卸載 會調(diào)用的方法,通常在這里我們會卸載微應(yīng)用的應(yīng)用實(shí)例
*/
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}

/**
* 可選生命周期鉤子,僅使用 loadMicroApp 方式加載微應(yīng)用時(shí)生效
*/
export async function update(props) {
console.log('update props', props);
}

2.2 新建 vue.config.js,配置如下

module.exports = {
devServer:{
port:10000,
headers:{
// 解決跨域
'Access-Control-Allow-Origin':'*'
}
},
configureWebpack:{
output:{
// 把子應(yīng)用打包成 umd 庫格式
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
}
}
}

*基于 qiankun 微前端項(xiàng)目 (實(shí)踐代碼庫)

https://github.com/jiasx/mic-front-vue2.0

https://github.com/jiasx/mic-front-react

責(zé)任編輯:姜華 來源: 前端學(xué)苑
相關(guān)推薦

2020-05-06 09:25:10

微前端qiankun架構(gòu)

2022-07-27 22:56:45

前端應(yīng)用緩存qiankun

2021-11-24 22:42:15

WorkManagerAPI

2020-03-09 17:28:51

NoSQLMongoDB數(shù)據(jù)庫

2020-09-10 06:56:12

SringMVC源碼參數(shù)

2021-01-14 07:15:19

NginxWeb服務(wù)器

2021-07-29 07:55:20

React實(shí)踐代碼

2022-03-04 08:17:53

PageRank網(wǎng)絡(luò)等級

2021-07-08 07:30:13

Webpack 前端Tree shakin

2020-08-03 10:00:11

前端登錄服務(wù)器

2022-09-20 07:33:15

Jenkinshttps://mp

2021-08-07 21:51:17

服務(wù)器網(wǎng)站部署

2023-01-12 22:00:48

2021-10-28 07:10:21

rollupPlugin插件編寫

2020-01-08 09:44:59

運(yùn)維架構(gòu)技術(shù)

2023-02-20 09:55:00

微服務(wù)框架單體架構(gòu)

2025-02-24 12:20:14

2021-08-15 22:52:30

前端H5拼圖

2021-04-14 15:54:20

Kubernetes程序工具
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號