日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

微前端解读

發布時間:2024/1/8 HTML 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微前端解读 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微前端
目標
高質量:代碼對標一線互聯網大廠
全流程:子應用 -> 主應用 -> 服務端 -> 發布平臺
前端架構
初始
無架構, 前端代碼內嵌到后端應用中
而后端采用的是mvc架構, 將視圖層、數據層和控制層做分離, 缺點是重度依賴開發環境, 代碼混淆嚴重
前后端分離架構
將前端代碼從后端環境中分離出來(Ajax促進了前后端分離架構的發展)多頁面架構, 但是缺點是前端缺乏獨立的部署能力, 整體依賴后端環境
單頁面架構
各種打包、構建工具應運而生, 誕生了多元化前端開發方式, 使得前端開發可以脫離整體的后端環境
打包:gulp, webpack, vite
框架:vue, react
UI庫:antd, element
優勢:切換頁面無刷新瀏覽器, 用戶體驗好; 組件化開發方式, 極大地提升了代碼的復用率
缺點:不利于SEO優化, 首次渲染會出現較長時間的白屏
大前端時代
后端框架:express, koa
包管理工具:npm, yarn
node版本管理工具:nvm
微前端架構
與技術棧無關
主框架不限制接入應用的技術棧, 微應用具備完全自主權
獨立開發, 獨立部署
增量升級
是一種非常好的實施漸進式重構的手段和策略
微應用倉庫獨立, 前后端可獨立開發, 主框架自動完成同步更新
獨立運行時, 每一個微應用之間狀態隔離, 運行時狀態不共享
劣勢:接入難度較高; 移動端少, 管理端多
軟件設計原則與分層
單一職責原則
概念:永遠不應該有多于一個原因來改變某個類
理解:對于一個類而言, 應該僅有一個引起它變化的原因
應用:如果一個類擁有了兩種職責, 那就可以將這個類分成兩個類
開放封閉原則
概念:軟件實體擴展應該是開放的, 但對于修改應該是封閉的
理解:對擴展開放, 對修改封閉, 可以去擴展類, 但不要去修改類
應用:當需求有改動, 盡量用繼承或者組合的形式來擴展類的功能, 而不是直接修改類的代碼
里氏替換原則
理解:父類一定是可以被子類替換的
最少知識原則
概念:只與你最直接的對象交流
理解:低耦合, 高內聚
應用:做系統設計時, 盡量減小依賴關系
接口隔離原則
概念:一個類與另一個類之間的依賴性, 應該依賴于盡可能小的接口
理解:不要對外暴露沒有實際意義的接口, 用戶不應該依賴他不需要的接口
應用:當需要對外暴露接口時, 如果是非必要對外提供, 盡量刪除
依賴倒置原則
概念:高層模塊不應該依賴于低層模塊, 它們應該依賴于抽象, 抽象不應該依賴于細節, 細節應該依賴于抽象
理解:應該面向接口編程, 不應該面向實現類編程
架構種類
系統級架構
應用在整個系統內, 如與后臺服務如何通信, 與第三方系統如何集成
設計前端首要條件:了解前端系統與其它系統之間的關系(業務關系和協作機制)
設計后端:只需要規定與后臺數據傳遞的機制(api設計規則, oauth的token機制, 數據傳遞cookie)
應用級架構
可以看做是系統級架構的細化
模塊級架構
這部分內容是我們在開始業務編碼之前的設計工作, 可以叫做迭代
代碼級架構
規范與原則
代碼質量以及改善
規范而非默契
微前端
在一個系統內微前端應用是應用間的架構方案
在多個應用之間, 微前端則是一種系統間的架構方案
微前端是將多個前端應用以某種形式結合在一起進行應用
目的
解決單體應用在一個較長的時間跨度下, 由于參與的人員、團隊的增多、變遷, 從一個普通應用演變成一個巨應用后所帶來的不可維護問題
單實例
同一個時刻, 只有一個子應用被展示, 子應用具備一個完整的應用生命周期
多實例
通常基于url的變化做子應用的切換
同一時刻可展示多個子應用
實現方式
1、iframe
優勢:技術成熟, 支持頁面嵌入, 天然支持運行沙箱隔離、獨立運行
劣勢:頁面之間可以是不同域名的, 需要對應設計通訊機制, 如何監聽、傳參等內容
2、web component
優勢:支持自定義元素; 支持shadow dom, 并可通過關聯進行控制; 支持模板和插槽的功能, 引入自定義組件內容
劣勢:需要重寫當前的項目; 生態系統不完善, 兼容性問題比較大; 設計架構過于復雜
3、自研微前端框架
路由分發; 主應用控制路由匹配和子應用加載, 共享依賴加載
項目架構設計
主應用
注冊子應用
加載、渲染子應用
路由匹配(activeWhen, rules - 由框架判斷)
獲取數據(公共依賴, 通過數據做鑒權處理)
通信(父子通信, 子父通信)
子應用
渲染
監聽通信(主應用傳遞過來的數據)
微前端框架
子應用的注冊
有開始的內容(應用加載完成)
路由更新判斷
匹配對應的子應用
加載子應用的內容
完成所有依賴項的執行
將子應用渲染在固定的容器內
公共事件管理
異常捕獲和報錯
全局狀態管理內容
沙箱隔離
通信機制
理解微前端
對比微服務
對于微服務來說, 模塊分開解耦基本就完事了, 但是微前端不一樣, 前端應用在運行時卻是一個整體, 需要整合, 甚至還需要交互、通信
什么是微前端
是一種由獨立交付的多個前端應用組成整體的架構風格
更加具體的來說呢, 微前端將前端應用分解成一些更小、更簡單的能夠獨立開發、測試、部署的小塊, 而在用戶看來仍然是內聚的單個產品
框架與方案對比
single-spa - 代碼簡潔
qiankun - 基于single-spa封裝的, 上手快, 文檔比較豐富, 最優選
icestark - 阿里封裝的框架
主應用創建
// 創建文件夾
mkdir qiankun-example
// 進入文件夾
cd qiankun-example
// 初始化
npm init
// 查看是否安裝vue-cli
vue --version
// 如果沒有, 則先全局安裝
npm/yarn install/add -g @vue/cli
// 創建主應用
vue create main
修改外層package.json啟動命令
“scripts”: {
“start:main”: "cd main && npm run serve"
}
可以通過npm run start:main來啟動主應用
vue子應用創建
vue create sub-vue
修改外層package.json啟動命令
“scripts”: {
“start:sub-vue”: "cd sub-vue && npm run serve"
}
可以通過npm run start:sub-vue來啟動主應用
react子應用創建
// 首先需要安裝腳手架create-react-app
npm install -g create-react-app
// 創建react子應用
create-react-app sub-react
修改外層package.json啟動命令
“scripts”: {
“start:sub-react”: “cd sub-react && npm run start”
}
可以通過npm run start:sub-react來啟動主應用
html子應用創建
mkdir sub-html
cd sub-html
npm init
文件目錄結構
|-js
|–main.js
index.html
package.json
配置sub-html的package.json
cnpm install -D cross-env http-server
“main”: “index.html”,
“scripts”: {
“start”: "cross-env PUBLIC_PATH=/ http-server ./ -p 7800 --cors"
},
“devDependencies”: {
“cross-env”: “^7.0.3”,
“http-server”: "^14.1.0"
}
修改外層package.json啟動命令
“scripts”: {
“start:sub-html”: "cd sub-html && npm run start"
}
可以通過npm run start:sub-html來啟動主應用
主應用注冊微應用
安裝qiankun
cnpm install qiankun -S
配置.env文件 VUE_APP_SUB_VUE=//localhost:7777/subapp/sub-vue VUE_APP_SUB_REACT=//localhost:7778/subapp/sub-react VUE_APP_SUB_HTML=//localhost:7779/subapp/sub-html
注冊啟動微應用
import { registerMicroApps, start, setDefaultMountApp } from ‘qiankun’
import microApps from ‘./micro-app’ 
// 注冊微應用(子應用)
registerMicroApps(microApps, {
// 監聽它的一個注冊的一個生命周期
beforeLoad: app => {},
beforeMount: [
app => {}
],
afterMount: [
app => {}
],
afterUnmount: [
app => {}
]
})
// 啟動
start()
// 設置默認訪問的路由
setDefaultMountApp(’/sub-vue’)
// microApps.js
const microApps = [
{
name: ‘sub-vue’, // 子應用的名稱
entry: process.env.VUE_APP_SUB_VUE, // 入口, 通過環境配置文件獲取
activeRule: ‘/sub-vue’, // 在子應用里面使用怎么樣的路由規則去訪問
container: ‘#subapp-viewport’, // 子應用的內容在主應用的哪個盒子里顯示出來
props: {
// 做數據的交互
routerBase: ‘/sub-vue’,
getGlobalState: ‘’
}
},
{
name: ‘sub-react’,
entry: process.env.VUE_APP_SUB_REACT,
activeRule: ‘/sub-react’,
container: ‘#subapp-viewport’,
props: {
// 做數據的交互
routerBase: ‘/sub-react’,
getGlobalState: ‘’
}
},
{
name: ‘sub-html’,
entry: process.env.VUE_APP_SUB_HTML,
activeRule: ‘/sub-html’,
container: ‘#subapp-viewport’,
props: {
// 做數據的交互
routerBase: ‘/sub-html’,
getGlobalState: ‘‘
}
}
]
export default microApps
vue子應用開發配置
配置vue.config.js
const { name } = require(’./package.json’) 
module.exports = {
publicPath: ‘/subapp/sub-vue’,
configureWebpack: {
output: {
library: ${name}-[name],
libraryTarget: ‘umd’,
jsonpFunction: webpackJsonp_${name}
}
},
devServer: {
port: process.env.VUE_APP_PORT,
headers: {
‘Access-Control-Allow-Origin’: ‘'
}
}
}
修改main.js
import './public-path’
import Vue from 'vue’
import App from './App.vue’
import routes from './router’
import store from './store’
import VueRouter from ‘vue-router’
Vue.config.productionTip = false
Vue.use(VueRouter)
// 渲染頁面
let instance = null // vue
function render (props = {}) {
const { container, routerBase } = props
const router = new VueRouter({
mode: 'history’
base: window.POWERED_BY_QIANKUN ? routerBase : process.env.BASE_URL,
routes
})
instance = new Vue({
router,
store,
render: h => h(App)
}).KaTeX parse error: Expected 'EOF', got '#' at position 44: …querySelector('#?app') : '#app')…destroy()
instance.KaTeX parse error: Expected 'EOF', got '}' at position 42: …ance = null }? 重新修改的路由文件 /…{process.env.VUE_APP_PORT}KaTeX parse error: Expected 'EOF', got '}' at position 47: … return }? // esli…{process.env.BASE_URL}/} })() react子應用開發配置 安裝依賴, 修改package.json cnpm install react-app-rewired -D "scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build" } // 注意react的版本, 太高版本改造的過于大, 建議使用16 "dependencies": { "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.2", "@testing-library/user-event": "^13.5.0", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "5.0.0", "web-vitals": "^2.1.4" }, "devDependencies": { "react-app-rewired": "^2.1.11" } 建立config-overrides.js配置文件修改webpack配置 const { name } = require('./package.json') module.exports = { webpack: (config) => { config.output.publicPath =//localhost: p r o c e s s . e n v . P O R T {process.env.PORT} process.env.PORT{process.env.PUBLIC_URL}config.output.library =KaTeX parse error: Expected group after '_' at position 114: …= `webpackJsonp_?{name}`
return config
},
devServer: (configFunction) => {
return function (proxy, allowedHost) {
const config = configFunction(proxy, allowedHost)
config.open = false
config.hot = false
config.headers = {
‘Access-Control-Allow-Origin’: '’,
}
return config
}
}
}
修改入口文件
import './public-path’
import React from ‘react’;
import ReactDOM from 'react-dom’
import ‘./index.css’;
import App from ‘./App’;
import reportWebVitals from ‘./reportWebVitals’;
function render () {
ReactDOM.render(
<React.StrictMode>
<App /
</React.StrictMode>,
document.getElementById(‘root’)
)
} 
// 獨立運行
if (!window.POWERED_BY_QIANKUN) {
render()
} 
// 微應用環境
/**

  • bootstrap 只會在微應用初始化的時候調用一次,下次微應用重新進入時會直接調用 mount 鉤子,不會再重復觸發 bootstrap。
  • 通常我們可以在這里做一些全局變量的初始化,比如不會在 unmount 階段被銷毀的應用級別的緩存等。
    /
    export async function bootstrap () {
    console.log(‘react app bootstraped’);
    }
    /*
  • 應用每次進入都會調用 mount 方法,通常我們在這里觸發應用的渲染方法
    /
    export async function mount(props) {
    console.log(‘基座下發的能力:’, props
    render()
    }
    /*
  • 應用每次 切出/卸載 會調用的方法,通常在這里我們會卸載微應用的應用實例
    */
    export async function unmount() { ReactDOM.unmountComponentAtNode(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();
    // public-path.js
    if (window.POWERED_BY_QIANKUN) {
    // eslint-disable-next-line
    webpack_public_path = window.INJECTED_PUBLIC_PATH_BY_QIANKUN;
    //webpack_public_path = window.INJECTED_PUBLIC_PATH_BY_QIANKUN;
    }
    html子應用開發配置
    // ./js/main.js
    const render = (options)=> {
    document.querySelector(’#current-env’).innerHTML = ‘qiankun’
    return Promise.resolve()
    }
    (win => {
    win[‘pureHtml’] = {
    bootstrap: () => {
    console.log(‘purehtml bootstrap’)
    return Promise.resolve()
    },
    mount: (options) => {
    console.log(‘purehtml mount’, options)
    return render(options)
    },
    unmount: () => {
    console.log(‘purehtml unmount’)
    return Promise.resolve()
    }
    }
    })(window)
     html子應用    純原生HTML子應用, 當前處于 獨立運行 環境。   項目打包服務配置 安裝依賴  cnpm install npm-run-all -D "scripts": { "start": "npm-run-all --parallel start:*", "start:main": "cd main && npm run start", "start:sub-vue": "cd sub-vue && npm run start", "start:sub-react": "cd sub-react && npm run start", "start:sub-html": "cd sub-html && npm run start", "build": "npm-run-all build:* && bash ./scripts/bundle.sh", "build:sub-react": "cd sub-react && npm run build", "build:sub-vue": "cd sub-vue && npm run build", "build:sub-html": "cd sub-html && npm run build",  "build:main": "cd main && npm run build" }, scripts/bundle.sh #!/bin/bash rm -rf ./dist mkdir ./dist mkdir ./dist/subapp # sub-react子應用 cp -r ./sub-react/build/ ./dist/subapp/sub-react/  # sub-vue子應用 cp -r ./sub-vue/dist/ ./dist/subapp/sub-vue/ # sub-html子應用 cp -r ./sub-html/dist/ ./dist/subapp/sub-html/ # main基座 cp -r ./main/dist/ ./dist/main  # cd ./dist # zip -r mp$(date +%Y%m%d%H%M%S).zip * # cd .. echo 'bundle.sh execute success.

總結

以上是生活随笔為你收集整理的微前端解读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。