第3章 微前端框架 single-spa
https://zh-hans。single-spa。js。org/
single-spa:https://single-spa。js。org/ 是一個實現微前端架構的框架。
在 single-spa 框架中有三種類型的微前端應用:
single-spa-application / parcel:微前端架構中的微應用,可以使用 vue、react、angular 等框架。
single-spa root config:建立微前端容器應用。
utility modules:公共模組應用,非渲染元件,用於跨應用共享 javascript 邏輯的微應用。
3-1 建立容器應用
安裝 single-spa 腳手架工具:
npm install create-single-spa@2。0。3 -g
建立微前端容器應用:
create-single-spa
應用資料夾填寫 container
應用選擇 single-spa root config
組織名稱填寫 study組織名稱可以理解為團隊名稱,微前端架構允許多團隊共同開發應用,組織名稱可以標識應用由哪個團隊開發。應用名稱的命名規則為
@組織名稱/應用名稱
,比如
@study/todos
4。 啟動應用:
cd 。/singletest && npm start
5。 訪問應用:
localhost:9000
3-2 容器預設程式碼解析
src/xx-root-config。js
// 從框架中引入 兩個 方法,下面呼叫import { registerApplication, start } from “single-spa”;/* 註冊微前端應用 1。 name: 字串型別, 微前端應用名稱 “@組織名稱/應用名稱” 2。 app: 函式型別, 返回 Promise, 透過 systemjs 引用打包好的微前端應用模組程式碼 (umd) 3。 activeWhen: 路由匹配時啟用應用*/registerApplication({ name: “@single-spa/welcome”, app: () => System。import( “https://unpkg。com/single-spa-welcome/dist/single-spa-welcome。js” ), activeWhen: [“/”],});
// 當前組織的微應用引入示例// registerApplication({// name: “@xl/navbar”,// app: () => System。import(“@xl/navbar”),// activeWhen: [“/”]// });// start 方法必須在 single spa 的配置檔案中呼叫// 在呼叫 start 之前, 應用會被載入, 但不會初始化, 掛載或解除安裝。start({ // 是否可以透過 history。pushState() 和 history。replaceState() 更改觸發 single-spa 路由 // true 不允許 false 允許 (先了解,有印象) urlRerouteOnly: true,});
index。ejs
<!—— 匯入微前端容器應用 ——> <!—— import-map-overrides 可以覆蓋匯入對映 當前專案中用於配合 single-spa Inspector 除錯工具使用。 可以手動覆蓋專案中的 JavaScript 模組載入地址, 用於除錯。——><!—— 用於支援 Angular 應用 ——> <!—— ——> <!—— 用於覆蓋透過 import-map 設定的 JavaScript 模組下載地址 ——> <!—— 判斷是否是本地 ——> <% if (isLocal) { %> <!—— 模組載入器 ——> <!—— systemjs 用來解析 AMD 模組的外掛 ——> <% } else { %> <% } %>
<!—— single-spa 預載入 ——> <!—— Add your organization‘s prod import map URL to this script’s src ——> <!—— ——><!—— JavaScript 模組下載地址 此處可放置微前端專案中的公共模組 ——> <% if (isLocal) { %> <% } %>
3-3 建立基於 React 的微應用
3-3-1 建立 React 微應用
建立應用:
create-single-spa
,注意組織及專案名字,後面註冊微應用是會用到
應用目錄輸入 todos
框架選擇 react
修改應用埠 && 啟動應用
{ “scripts”: { “start”: “webpack serve ——port 9002”, }}
啟動應用:
npm start
3-3-2 註冊應用
將 React 專案的入口檔案註冊到基座應用 (容器應用) 中
\container\src\study-root-config。js :
// React —— todos registerApplication({ name: “@study/todos”, app: () => System。import(“@study/todos”), activeWhen: [“/todos”]});
指定微前端應用模組的引用地址:
(可以直接訪問對應應用伺服器,有提示 URL 載入地址)
<% if (isLocal) { %> <% } %>
指定公共庫的訪問地址,預設情況下,應用中的 react 和 react-dom 沒有被 webpack 打包, single-spa 認為它是公共庫,不應該單獨打包。
修改預設應用程式碼,已獨立頁面展示應用內容
container\src\study-root-config。js
// registerApplication({// name: “@single-spa/welcome”,// app: () =>// System。import(// “https://unpkg。com/single-spa-welcome/dist/single-spa-welcome。js”// ),// activeWhen: [“/”],// });// 修改預設應用註冊方式,獨立頁面展示應用內容registerApplication( “@single-spa/welcome”, () => System。import( “https://unpkg。com/single-spa-welcome/dist/single-spa-welcome。js” ), location=>location。pathname === ‘/’);
3-3-3 指定應用渲染位置
micro\container\src\index。ejs
<!—— 指定應用展示位置 ——>
micro\todos\src\study-todos。js
const lifecycles = singleSpaReact({ React, ReactDOM, // 渲染根元件 rootComponent: Root, // 錯誤邊界函式 errorBoundary(err, info, props) { // Customize the root error boundary for your microfrontend here。 return null; }, // 指定根元件的渲染位置 domElementGetter:()=>document。getElementById(‘myreact’)});
3-3-4 React 應用程式碼解析
micro\todos\src\study-todos。js
import React from “react”;import ReactDOM from “react-dom”;// single-spa-react 用於建立使用 React 框架實現的微前端應用import singleSpaReact from “single-spa-react”;// 用於渲染在頁面中的根元件 就相當於傳統React應用的App。js檔案import Root from “。/root。component”;const lifecycles = singleSpaReact({ React, ReactDOM, // 渲染根元件 rootComponent: Root, // 錯誤邊界函式 errorBoundary(err, info, props) { // Customize the root error boundary for your microfrontend here。 // return null; return ()=>
3-3-5 React 微前端路由配置
準備好兩個路由元件
micro\todos\src\home。js && micro\todos\src\about。js
import React, { Component } from ‘react’export default class home extends Component { render() { return (
什麼是快樂星球
快樂星球就是學習微前端
micro\todos\src\root。component。js
import React from “react”;// 引入路由相關元件import {BrowserRouter, Switch, Route, Redirect, Link} from “react-router-dom”// 引入元件import Home from ‘。/home’import About from ‘。/about’export default function Root(props) { // return
路由檔案已公共模組引入,\micro\container\src\index。ejs
修改 webpack 配置檔案,排除路由模組打包,micro\todos\webpack。config。js
return merge(defaultConfig, { // modify the webpack config however you‘d like to by adding to this object externals: [“react-router-dom”]});
3-4 建立基於 Vue 的微應用
3-4-1 建立應用
建立應用:
create-single-spa
專案資料夾填寫 realworld
框架選擇 Vue
生成 Vue 2 專案
因為 vue && vue-router 需要透過公共模組打包,所以,在應用內部需要配置不打包
micro\realworld\vue。config。js
module。exports = { chainWebpack:config=>{ // 配置不打包 Vue 及 vue-router config。externals([“vue”,“vue-router”]) }}
修改專案啟動命令:micro\realworld\package。json
“scripts”: { “serve”: “vue-cli-service serve”, “start”: “vue-cli-service serve ——port 9003”, “build”: “vue-cli-service build”, “lint”: “vue-cli-service lint”, “serve:standalone”: “vue-cli-service serve ——mode standalone” },
註冊應用:micro\container\src\study-root-config。js
// Vue —— todosregisterApplication({ name: “@study/realworld”, app: () => System。import(“@study/realworld”), activeWhen: [“/realworld”],});
micro\container\src\index。ejs
載入 vue && vue-router
匯入應用,應用地址可以直接訪問應用後,在瀏覽器的提示中獲取;
<% if (isLocal) { %> <% } %>
3-4-2 應用路由配置
\micro\realworld\src\main。js
import Vue from ’vue‘;import singleSpaVue from ’single-spa-vue‘;import App from ’。/App。vue‘;import VueRouter from ’vue-router‘Vue。use(VueRouter)// 路由元件const Foo = { template: “
micro\realworld\src\App。vue
3-5 建立 utility modules
3-5-1 utility 獨立應用建立
用於放置跨應用共享的 JavaScript 邏輯,它也是獨立的應用,需要單獨構建單獨啟動。
建立應用:
create-single-spa
資料夾填寫 tools應用選擇
in-browser utility module (styleguide, api cache, etc)
修改埠,啟動應用, \micro\tools\package。json
“scripts”
: {
“start”
:
“webpack serve ——port 9005”
,
}
匯出公共方法 : micro\tools\src\study-tools。js
export function happyStar(who){ console。log(`${who} hahahhahahhah`) return ’happy star 之 快樂的源泉‘}
在模板檔案中宣告應用模組訪問地址 : micro\container\src\index。ejs
<% if (isLocal) { %> <% } %>
3-5-2 在 React 應用中使用該方法
MicroFrontends\micro\todos\src\about。js
import React, { useEffect, useState } from “react”;// 自定義鉤子函式function useToolsModule() { const [toolsModule, setToolsModule] = useState(); useEffect(() => { // 匯入,非同步promise返回 System。import(“@study/tools”)。then(setToolsModule); }, []); return toolsModule;}function about() { var back = “”; // 呼叫鉤子函式 const toolsModule = useToolsModule(); if (toolsModule) { // 呼叫共享邏輯的方法 back = toolsModule。happyStar(“React todo”); } return (
快樂星球就是學習微前端——{back}
3-5-3 在 Vue 應用中使用該方法
micro\realworld\src\main。js
// 路由元件// const Foo = { template: “
micro\realworld\src\components\Foo。vue
什麼是快樂星球 {{ msg }}