微前端
阿新 • • 發佈:2020-11-16
隨著專案工程越來越大,打包慢、載入慢等問題也隨之而來,想著有什麼方案可以解決呢?偶然之間看到微前端的概念,那什麼是微前端呢?
微前端主要是借鑑後端微服務的概念。簡單地說,就是將一個巨無霸(Monolith)的前端工程拆分成一個一個的小工程。別小看這些小工程,它們也是“麻雀雖小,五臟俱全”,完全具備獨立的開發、執行能力。整個系統就將由這些小工程協同合作,實現所有頁面的展示與互動。上面是一些網上摘抄的概念,那怎麼落地呢?
找了半天,終於找到了,它就是阿里的qiankun框架基於single-spa構建,下面是具體的構建流程:
1、新建一個專案;
2、cd /projectname -> npm init 工程
· 3、cnpm install qiankun -S 或 yarn add qiankun
4、專案結構
5、index.js
import { registerMicroApps, setDefaultMountApp, start, runAfterFirstMounted } from 'qiankun'; import render from './VueRender'; render({ loading: true }); const loader = loading => render({ loading }); registerMicroApps( [ { name:'bigScreen', entry: '//localhost:7101', container: '#subapp-viewport', loader, activeRule: '/bigScreen', }, { name: 'terryMusic', entry: '//localhost:8080', container: '#subapp-viewport', loader, activeRule: '/terryMusic', }, ], { beforeLoad: [ 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); }, ], }, ); /** * Step3 設定預設進入的子應用 */ setDefaultMountApp('/bigScreen'); /** * Step4 啟動應用 */ start(); runAfterFirstMounted(() => { console.log('[MainApp] first app mounted'); });
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Terry - MicroFront</title> </head> <body> <div class="mainapp"> <!-- 標題欄 --> <header class="mainapp-header"> <h1>Terry微前端應用落地</h1> </header> <div class="mainapp-main"> <!-- 側邊欄 --> <ul class="mainapp-sidemenu"> <li onclick="push('/bigScreen')">big-screen</li> <li onclick="push('/terryMusic')">terry-music</li> </ul> <!-- 子應用 --> <main id="subapp-container"></main> </div> </div> <script> function push(subapp) { history.pushState(null, subapp, subapp) } </script> </body> </html>
package.json
{ "name": "terry-micro-front", "version": "1.0.0", "description": "微前端", "main": "index.js", "scripts": { "start": "webpack-dev-server" }, "author": "terry", "license": "ISC", "dependencies": { "@babel/core": "^7.7.2", "@babel/plugin-transform-react-jsx": "^7.7.0", "@babel/preset-env": "^7.7.1", "babel-loader": "^8.0.6", "cross-env": "^7.0.2", "css-loader": "^3.2.0", "html-webpack-plugin": "^3.2.0", "less-loader": "^6.2.0", "qiankun": "^2.3.1", "style-loader": "^1.0.0", "vue": "^2.6.12", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.9.0" } }
VueRender:用於載入vue專案
import Vue from 'vue/dist/vue.esm'; function vueRender({ loading }) { return new Vue({ template: ` <div id="subapp-container"> <h4 v-if="loading" class="subapp-loading">Loading...</h4> <div id="subapp-viewport"></div> </div> `, el: '#subapp-container', data() { return { loading, }; }, }); } let app = null; export default function render({ loading }) { if (!app) { app = vueRender({ loading }); } else { app.loading = loading; } }
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './index.js', devtool: 'source-map', devServer: { port: '7099', clientLogLevel: 'warning', disableHostCheck: true, compress: true, headers: { 'Access-Control-Allow-Origin': '*', }, historyApiFallback: true, overlay: { warnings: false, errors: true }, }, output: { publicPath: '/', }, mode: 'development', resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], }, module: { rules: [ { test: /\.jsx?$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: ['@babel/plugin-transform-react-jsx'], }, }, }, { test: /\.(le|c)ss$/, use: ['style-loader', 'css-loader', 'less-loader'], }, ], }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: './index.html', minify: { removeComments: true, collapseWhitespace: true, }, }), ], };
子應用配置:Vue專案為例:
成品:
以上就是整個專案搭建過程以及程式碼,有興趣的可以一起學習哦!