>[success] # 簡單上手 -- single-spa
~~~
1.在 'single-spa' 方案中,應用被分為兩類:基座應用和子應用。基座應用是整體父級,內部子應用在基座應用中
和單頁應用的實現原理類似,'single-spa' 會在基座應用中維護一個路由注冊表,每個路由對應一個子應用。基座應用啟
動以后,當我們切換路由時,如果是一個新的子應用,會動態獲取子應用的 js 腳本,然后執行腳本并渲染出相應的頁
面;如果是一個已經訪問過的子應用,那么就會從緩存中獲取已經緩存的子應用,激活子應用并渲染出對應的頁面。
~~~
>[info] ## 創建過程
~~~
1.'npm install create-single-spa -g' -- 安裝sigle-spa 腳手架
2.'create-single-spa 基座項目文件名' -- 舉個例子'create-single-spa c' 自動創建一個c 文件夾內部是生成的,如果不是
全局安裝需要通過'npx' 執行腳本命令,基座代碼,當然執行'create-single-spa' 會出現一下選擇
2.1. 應用文件夾填寫 container
2.2. 應用選擇 single-spa root config
2.3. 組織名稱填寫 study 組織名稱可以理解為團隊名稱,微前端架構允許多團隊共同開發應用,組織名稱可以標識應用
由哪個團隊開發。應用名稱的命名規則為 @組織名稱/應用名稱 ,比如 @study/todos
3.'create-single-spa 文件名' -- 這時候選擇.'single-spa-application / parcel':微前端架構中的微應用,可以使用 vue、
react、angular 等框架
注關于幾個選項詳細解釋:
'single-spa root config':創建微前端容器應用。
'single-spa applications':為一組特定路由渲染組件的微前端。
'single-spa parcels': 不受路由控制,渲染組件的微前端。
'utility modules': 非渲染組件,用于暴露共享javascript邏輯的微前端。
~~~

>[info] ## 生成的基座文件介紹
~~~js
1.生成的目錄結構
base-root
├─ src
│ ├─ index.ejs
│ └─ study-root-config.js
├─ package-lock.json
├─ package.json
└─ webpack.config.js
2.創建基座后發現自動生成以下幾個關鍵文件
2.1.'index.ejs' -- 所有微前端應用共享的根 HTML 頁面,主要利用systemjs 實現'importmap' 做到按需導入
2.2.'*-root-config.js' -- 這是注冊微前端應用的配置文件
2.3.'webpack.config.js' -- webpack配置文件
~~~
>[danger] ##### webpack.config.js
~~~
1.這個文件主要導入了 "webpack-config-single-spa",一個可共享的、可定制的 webpack 配置,用于實用程序模塊
和 single-spa 應用程序,就是已經幫忙做好的關于'single-spa的webpack 文件'
2.對下面'disableHtmlGeneration' 變量做一個說明,默認為false,禁用html-webpack-plugin (and
standalone-single-spa-webpack-plugin)。下面案例設置為true 是因為自己配置了'html-webpack-plugin'
~~~
~~~
const { merge } = require("webpack-merge");
const singleSpaDefaults = require("webpack-config-single-spa");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = (webpackConfigEnv, argv) => {
const orgName = "study";
const defaultConfig = singleSpaDefaults({
orgName,
projectName: "root-config",
webpackConfigEnv,
argv,
disableHtmlGeneration: true,
});
return merge(defaultConfig, {
// modify the webpack config however you'd like to by adding to this object
plugins: [
new HtmlWebpackPlugin({
inject: false,
template: "src/index.ejs",
// 模版需要的參數,這里也就是為什么在'index.ejs' 會看到'isLocal' 變量名
templateParameters: {
isLocal: webpackConfigEnv && webpackConfigEnv.isLocal,
orgName,
},
}),
],
});
};
~~~
[官方介紹](https://single-spa.js.org/docs/create-single-spa/#create-single-spa)
>[danger] ##### study-root-config.js -- 文件
~~~
1.創建完基座后會出現一個'study-root-config.js' 文件,這是注冊微前端應用的配置文件,可以理解成路由文件
不過這個路由控制的是對應微前端展現對應項目
2.這個文件的名字來源,其實來自'webpack.config.js'文件中的'webpack-config-single-spa'配置
中,也就是其對webpack 的入口文件命名,點開'webpack-config-single-spa'就可以看到。
entry: path.resolve(
process.cwd(),
`src/${opts.orgName}-${opts.projectName}`
),
其中打包入口地址可以看到是'orgName' 和'projectName' 拼接得到的,這兩個屬性不難發現其實
在'webpack.config.js' 中設置的。到此這里變明白了'study-root-config.js'文件名字是如何生成的
~~~
~~~
import { registerApplication, start } from "single-spa";
/*
注冊微前端應用
1.name: 字符串類型, 微前端應用名稱 "@組織名稱/應用名稱"
2.app: 函數類型, 返回 Promise, 通過 systemjs 引用打包好的微前端應用模塊代碼 (umd)
3.activeWhen: 路由匹配時激活應用
*/
registerApplication({
name: "@study/root-config",
app: () =>
System.import(
"https://unpkg.com/single-spa-welcome/dist/single-spa-welcome.js"
),
activeWhen: ["/react"],
});
// start 方法必須在 single spa 的配置文件中調用
// 在調用 start 之前, 應用會被加載, 但不會初始化, 掛載或卸載.
start({
// 是否可以通過 history.pushState() 和 history.replaceState() 更改觸發 single-spa 路由
// true 不允許 false 允許
urlRerouteOnly: true,
});
~~~
>[danger] ##### index.ejs
~~~
1.所有微前端應用共享的根 HTML 頁面,主要利用systemjs 實現'importmap' 做到按需導入
~~~
~~~html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Root Config</title>
<!-- async/await 解析包-->
<script src="https://cdn.jsdelivr.net/npm/regenerator-runtime@0.13.7/runtime.min.js"></script>
<!--
This CSP allows any SSL-enabled host and for arbitrary eval(), but you should limit these directives further to increase your app's security.
Learn more about CSP policies at https://content-security-policy.com/#directive
-->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self' https: localhost:*; script-src 'unsafe-inline' 'unsafe-eval' https: localhost:*; connect-src https: localhost:* ws://localhost:*; style-src 'unsafe-inline' https:; object-src 'none';"
/>
<meta name="importmap-type" content="systemjs-importmap" />
<!-- 當加載基座時,需要導入single-spa -->
<script type="systemjs-importmap">
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js"
}
}
</script>
<link
rel="preload"
href="https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js"
as="script"
/>
<!-- Add your organization's prod import map URL to this script's src -->
<!-- <script type="systemjs-importmap" src="/importmap.json"></script> -->
<% if (isLocal) { %>
<script type="systemjs-importmap">
{
"imports": {
"@study/root-config": "//localhost:9000/study-root-config.js"
}
}
</script>
<% } %>
<!-- 需要systemJS模塊化和amd解析 -->
<script src="https://cdn.jsdelivr.net/npm/import-map-overrides@2.2.0/dist/import-map-overrides.js"></script>
<% if (isLocal) { %>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/amd.js"></script>
<% } else { %>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/system.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.3/dist/extras/amd.min.js"></script>
<% } %>
</head>
<body>
<noscript> You need to enable JavaScript to run this app. </noscript>
<main></main>
<script>
// 加載基座應用
System.import('@study/root-config')
</script>
<import-map-overrides-full
show-when-local-storage="devtools"
dev-libs
></import-map-overrides-full>
</body>
</html>
~~~
* [Configuring single-spa官網對參數的介紹](https://zh-hans.single-spa.js.org/docs/configuration)
>[danger] ##### 不通過腳手架創建基座步驟
~~~
1.通過腳手架創建的基座基本已經明確了一個基座創建主要幾個解析文件
1.1.'webpack-config.js'作為使用webpack打包配置文件,因此相對的主要需要的幾個包'wepabck'
'webpack-cli',還用html作為模板相對的也需要' html-webpack-plugin',通過官方提供的將一些基礎
配置已經配置好的'webpack-config-single-spa'
1.2.到了webpack入口文件,'src/*-*.js' 上面分析過這兩個'*' 具體名字是根據.'webpack-config.js'
中'orgName' 和'projectName' 拼接得到的,也可以覆蓋自定義,入口文件主要是為了作為
各個路由調用微前端的映射文件這里需要"single-spa" 這個包來幫助
2.分析所需要的包和各個文件之間的關系,如果沒有腳手架,想自己生成基座文件相對的第一步
安裝上面提到的文件,按照對應規則創建文件即可
~~~
>[info] ## 創建微應用 -- 子應用的構建
~~~
1.已經明確了'single-spa' 基座應用是類似路由映射,當我們創建好了子應用的時候,需要做的
是在基座應用的入口做好路由映射舉個例子和基座聯動,注冊微應用在'*-*-config.js' 中
registerApplication({
name: "@study/vue",
app: () => System.import("@study/vue-app"),
activeWhen: location => location.pathname.startsWith('/vue'),
});
下一步需要在'index.ejs' 聲明打包后的文件,例如下面vue項目啟動的端口是3000,并且vuecli打包后的默認文件都是
在'js/app.js'
<% if (isLocal) { %>
<script type="systemjs-importmap">
{
"imports": {
"@study/root-config": "//localhost:9000/study-root-config.js",
"@study/vue-app":"//localhost:3000/js/app.js"
}
}
</script>
<% } %>
2.'single-spa' 微應用的解決實現方案,對主流框架依舊提供了對應的封裝配置包例如
'webpack-config-single-spa-react'、'single-spa-vue' ,只要按照規則依舊可以對進行配置,
非主流框架可以按照下面步驟來做整體和基座的解決思路類似
3.子應用對應的需要對外暴露'bootstrap' 、'mount'、'unmount' 聲明周期
4.關于'app: System.import()'中值名字,其實這個是'System.js' 導入的用法,當你將
一個包打包成'system.js'規范的時候,注冊名字以spa-vue 的腳手架為例,當你通過打印
'npx vue-cli-service inspect --mode production > aa.js' 就可以發現'SystemJSPublicPathWebpackPlugin'
這里做了對應的映射,如果在細看會在'node_modules'找'vue-cli-plugin-single-spa',跟具體的配置可以發現這個名字
來源的代碼如下
const packageJsonPath = api.resolve("package.json");
const { name } = require(packageJsonPath);
即也就是你注冊對應項目的'package.json' 文件中的name
~~~
>[danger] ##### 非框架的微應用
~~~
1.只需要將你的webpack 配置和提供的webpack配置做合并即可
~~~
~~~js
const { merge } = require("webpack-merge")
const singleSpaDefaults = require("webpack-config-single-spa")
module.exports = () => {
const defaultConfig = singleSpaDefaults({
// 組織名稱
orgName: "study",
// 項目名稱
projectName: "root"
})
return merge(defaultConfig, { devServer: { port: 9001 } }) }
~~~
>[danger] ##### vue 創建的微前端主要配置 -- main.js
~~~js
import Vue from "vue";
import singleSpaVue from "single-spa-vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
const vueLifecycles = singleSpaVue({
Vue,
appOptions: {
render (h) {
return h(App, {
props: {
// single-spa props are available on the "this" object. Forward them to your component as needed.
// https://single-spa.js.org/docs/building-applications#lifecyle-props
// if you uncomment these, remember to add matching prop definitions for them in your App.vue file.
/*
name: this.name,
mountParcel: this.mountParcel,
singleSpa: this.singleSpa,
*/
},
});
},
router,
store,
},
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
~~~
>[info] ## 總結
~~~
1.在使用就像名字應'single-spa' 做的一種單頁面微前端的形式,通過一個基座,要創建一個關于子應用的路由注冊
表,然后根據路由注冊表使用 single-spa 提供的 registerApplication 方法注冊子應用,最后在基座應用掛載完成
,執行 single-spa 提供的 start 方法即可,各個微前端子應用配合官方提供的配置,并暴露出'bootstrap'
'mount'、'unmount' 這些暴露的屬性最終和基座配合控制各個微前端交互
~~~
- 工程化 -- Node
- vscode -- 插件
- vscode -- 代碼片段
- 前端學會調試
- 谷歌瀏覽器調試技巧
- 權限驗證
- 包管理工具 -- npm
- 常見的 npm ci 指令
- npm -- npm install安裝包
- npm -- package.json
- npm -- 查看包版本信息
- npm - package-lock.json
- npm -- node_modules 層級
- npm -- 依賴包規則
- npm -- install 安裝流程
- npx
- npm -- 發布自己的包
- 包管理工具 -- pnpm
- 模擬數據 -- Mock
- 頁面渲染
- 渲染分析
- core.js && babel
- core.js -- 到底是什么
- 編譯器那些術語
- 詞法解析 -- tokenize
- 語法解析 -- ast
- 遍歷節點 -- traverser
- 轉換階段、生成階段略
- babel
- babel -- 初步上手之了解
- babel -- 初步上手之各種配置(preset-env)
- babel -- 初步上手之各種配置@babel/helpers
- babel -- 初步上手之各種配置@babel/runtime
- babel -- 初步上手之各種配置@babel/plugin-transform-runtime
- babel -- 初步上手之各種配置(babel-polyfills )(未來)
- babel -- 初步上手之各種配置 polyfill-service
- babel -- 初步上手之各種配置(@babel/polyfill )(過去式)
- babel -- 總結
- 各種工具
- 前端 -- 工程化
- 了解 -- Yeoman
- 使用 -- Yeoman
- 了解 -- Plop
- node cli -- 開發自己的腳手架工具
- 自動化構建工具
- Gulp
- 模塊化打包工具為什么出現
- 模塊化打包工具(新) -- webpack
- 簡單使用 -- webpack
- 了解配置 -- webpack.config.js
- webpack -- loader 淺解
- loader -- 配置css模塊解析
- loader -- 圖片和字體(4.x)
- loader -- 圖片和字體(5.x)
- loader -- 圖片優化loader
- loader -- 配置解析js/ts
- webpack -- plugins 淺解
- eslit
- plugins -- CleanWebpackPlugin(4.x)
- plugins -- CleanWebpackPlugin(5.x)
- plugin -- HtmlWebpackPlugin
- plugin -- DefinePlugin 注入全局成員
- webapck -- 模塊解析配置
- webpack -- 文件指紋了解
- webpack -- 開發環境運行構建
- webpack -- 項目環境劃分
- 模塊化打包工具 -- webpack
- webpack -- 打包文件是個啥
- webpack -- 基礎配置項用法
- webpack4.x系列學習
- webpack -- 常見loader加載器
- webpack -- 移動端px轉rem處理
- 開發一個自己loader
- webpack -- plugin插件
- webpack -- 文件指紋
- webpack -- 壓縮css和html構建
- webpack -- 清里構建包
- webpack -- 復制靜態文件
- webpack -- 自定義插件
- wepack -- 關于靜態資源內聯
- webpack -- source map 對照包
- webpack -- 環境劃分構建
- webpack -- 項目構建控制臺輸出
- webpack -- 項目分析
- webpack -- 編譯提速優護體積
- 提速 -- 編譯階段
- webpack -- 項目優化
- webpack -- DefinePlugin 注入全局成員
- webpack -- 代碼分割
- webpack -- 頁面資源提取
- webpack -- import按需引入
- webpack -- 搖樹
- webpack -- 多頁面打包
- webpack -- eslint
- webpack -- srr打包后續看
- webpack -- 構建一個自己的配置后續看
- webpack -- 打包組件和基礎庫
- webpack -- 源碼
- webpack -- 啟動都做了什么
- webpack -- cli做了什么
- webpack - 5
- 模塊化打包工具 -- Rollup
- 工程化搭建代碼規范
- 規范化標準--Eslint
- eslint -- 擴展配置
- eslint -- 指令
- eslint -- vscode
- eslint -- 原理
- Prettier -- 格式化代碼工具
- EditorConfig -- 編輯器編碼風格
- 檢查提交代碼是否符合檢查配置
- 整體流程總結
- 微前端
- single-spa
- 簡單上手 -- single-spa
- 快速理解systemjs
- single-sap 不使用systemjs
- monorepo -- 工程
- Vue -- 響應式了解
- Vue2.x -- 源碼分析
- 發布訂閱和觀察者模式
- 簡單 -- 了解響應式模型(一)
- 簡單 -- 了解響應式模型(二)
- 簡單 --了解虛擬DOM(一)
- 簡單 --了解虛擬DOM(二)
- 簡單 --了解diff算法
- 簡單 --了解nextick
- Snabbdom -- 理解虛擬dom和diff算法
- Snabbdom -- h函數
- Snabbdom - Vnode 函數
- Snabbdom -- init 函數
- Snabbdom -- patch 函數
- 手寫 -- 虛擬dom渲染
- Vue -- minVue
- vue3.x -- 源碼分析
- 分析 -- reactivity
- 好文
- grpc -- 瀏覽器使用gRPC
- grcp-web -- 案例
- 待續