微前端 - Native Federation使用完整示例

? ? ? ?這是一個極簡化的 Angular 使用@angular-architects/native-federation 插件的微前端示例,只包含一個主應用和一個遠程應用。

完整示例展示

項目結構

federation-simple/
├── host-app/      # 主應用
└── remote-app/    # 遠程應用

創建遠程應用 (remote-app)

?初始化項目
ng new remote-app --standalone --minimal --style=css --routing=false
cd remote-app
npm install @angular-architects/native-federation --save-dev
配置 Native Federation
ng add @angular-architects/native-federation --project remote-app --port 4201
創建遠程組件

編輯 src/app/hello.component.ts:

import { Component } from '@angular/core';@Component({standalone: true,template: `<div style="border: 2px solid blue;padding: 20px;margin: 10px;border-radius: 5px;"><h2>Hello from Remote App!</h2><p>This component is loaded from the remote app</p></div>`
})
export class HelloComponent {}
配置暴露的模塊

編輯 federation.config.js:

module.exports = {name: 'remoteApp',exposes: {'./Hello': './src/app/hello.component.ts'},shared: {'@angular/core': { singleton: true, strictVersion: true },'@angular/common': { singleton: true, strictVersion: true },'rxjs': { singleton: true, strictVersion: true }}
};

創建主應用 (host-app)

初始化項目
ng new host-app --standalone --minimal --style=css --routing=true
cd host-app
npm install @angular-architects/native-federation @angular-architects/module-federation-tools --save-dev
配置 Native Federation
ng add @angular-architects/native-federation --project host-app --port 4200
創建主頁面

編輯 src/app/app.component.ts:

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';@Component({standalone: true,imports: [CommonModule, RouterOutlet],template: `<div style="padding: 20px;"><h1>Host Application</h1><nav><a routerLink="/" style="margin-right: 15px;">Home</a><a routerLink="/remote">Load Remote Component</a></nav><router-outlet></router-outlet></div>`
})
export class AppComponent {}
創建遠程組件加載頁面

創建 src/app/remote.component.ts:

在這里使用了<app-remote-hello> 那這個怎么來的呢?請見下面的關鍵點說明第四點!!!

import { Component, OnInit } from '@angular/core';
import { loadRemoteModule } from '@angular-architects/module-federation';@Component({standalone: true,template: `<div style="margin-top: 20px;"><h2>Remote Component</h2><div *ngIf="loading">Loading remote component...</div><div *ngIf="error" style="color: red;">Failed to load remote component: {{error}}</div><ng-container *ngIf="!loading && !error"><app-remote-hello></app-remote-hello></ng-container></div>`
})
export class RemoteComponent implements OnInit {loading = true;error: string | null = null;async ngOnInit() {try {await loadRemoteModule({remoteEntry: 'http://localhost:4201/remoteEntry.js',remoteName: 'remoteApp',exposedModule: './Hello'});this.loading = false;} catch (err) {this.error = err instanceof Error ? err.message : String(err);this.loading = false;}}
}
配置路由

編輯 src/app/app.routes.ts:

import { Routes } from '@angular/router';
import { RemoteComponent } from './remote.component';export const APP_ROUTES: Routes = [{ path: 'remote', component: RemoteComponent,providers: [// 注冊遠程組件{provide: 'remote-hello',useValue: {remoteEntry: 'http://localhost:4201/remoteEntry.js',remoteName: 'remoteApp',exposedModule: './Hello',componentName: 'Hello'}}]},{ path: '**', redirectTo: 'remote' }
];
配置應用

編輯 src/app/app.config.ts:

import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { APP_ROUTES } from './app.routes';
import { RemoteComponent } from '@angular-architects/module-federation-tools';export const appConfig: ApplicationConfig = {providers: [provideRouter(APP_ROUTES),importProvidersFrom(RemoteComponent.forRemote({type: 'module',remoteEntry: 'http://localhost:4201/remoteEntry.js',exposedModule: './Hello',componentName: 'Hello'}))]
};
配置 federation

編輯 federation.config.js:?

module.exports = {name: 'hostApp',remotes: {'remoteApp': 'http://localhost:4201/remoteEntry.js'},shared: {'@angular/core': { singleton: true, strictVersion: true },'@angular/common': { singleton: true, strictVersion: true },'@angular/router': { singleton: true, strictVersion: true },'rxjs': { singleton: true, strictVersion: true }}
};

運行應用

  1. 打開兩個終端窗口
  2. 在第一個終端中運行遠程應用
  3. 在第二個終端中運行主應用
  4. 訪問應用
  5. 在主應用中,點擊 "Load Remote Component" 鏈接將加載并顯示遠程組件

關鍵點說明

項目簡單說明下面三點:

  1. 遠程應用: remote中暴露一個了簡單的HelloCompoent并且配置了共享的 Angular 核心庫;

  2. 主應用: host中使用 了loadRemoteModule動態加載遠程組件,同時通過路由導航到遠程組件,并且配置了遠程模塊的引用;

  3. 共享依賴: remote項目和Host項目Angular 核心庫和 RxJS 被標記為共享單例,并且確保了版本兼容性

  4. <app-remote-hello> 這個selector怎么來的

app-remote-hello?是自定義元素,通過下面的方式創建和使用的:

組件名稱的生成規則: 當使用?@angular-architects/module-federation-tools?的?RemoteComponent時,組件名稱會自動按照以下規則生成:

app-remote-<componentName>
  • app?是 Angular 默認的前綴
  • remote?表示這是一個遠程組件
  • <componentName>?是你在配置中指定的組件名稱(這里是?hello

具體配置來源:在示例中,這個名稱來源于下面幾個地方的配置:

在?app.config.ts?中:

importProvidersFrom(RemoteComponent.forRemote({type: 'module',remoteEntry: 'http://localhost:4201/remoteEntry.js',exposedModule: './Hello',componentName: 'Hello'  // ← 這里定義了基礎名稱})
)

在?remote.component.ts?中:

<app-remote-hello></app-remote-hello>

完整的名稱轉換過程:

  • 你配置了?componentName: Hello
  • 系統會自動轉換為小寫形式:hello
  • 加上前綴?app-remote-?形成最終標簽名:app-remote-hello

如何自定義這個名稱:如果想使用不同的標簽名,可以這樣修改

// 在 app.config.ts 中
RemoteComponent.forRemote({// ...其他配置componentName: 'MyCustomHello',  // 自定義名稱elementName: 'my-hello-element'  // 自定義元素名(可選)
})// 然后在模板中使用
<my-hello-element></my-hello-element>

為什么能這樣使用:這是因為?@angular-architects/module-federation-tools?在底層做了以下工作:

  • 動態注冊了一個新的 Angular 組件

  • 將該組件定義為自定義元素(Custom Element)

  • 自動處理了組件名稱的轉換

  • 設置了與遠程組件的連接

驗證方法:如果你想確認這個組件是如何被注冊的,可以在瀏覽器開發者工具中:

  • 打開 Elements 面板

  • 找到?<app-remote-hello>?元素

  • 查看它的屬性,會發現它是一個 Angular組件

    • Angular 組件會有特殊屬性

      • 查看是否有?_nghost-*?和?_ngcontent-*?這類 Angular 特有的屬性

      • 例如:<app-remote-hello _ngcontent-abc="" _nghost-def="">

    • 檢查自定義元素定義

      • 在 Console 中輸入:document.querySelector('app-remote-hello').constructor.name

      • 如果是 Angular 組件,通常會顯示?HTMLElement(因為 Angular 組件最終是自定義元素)

?參考資料:

核心資源

  1. @angular-architects/native-federation 官方文檔
    📖?GitHub 倉庫 & 文檔

    • 包含安裝指南、配置選項和基本用法

  2. Module Federation 概念解釋
    📖?Webpack 官方文檔

    • 理解微前端的核心機制


教程文章

  1. Angular 微前端完整指南
    📖?Angular Architects 博客

    • 含代碼示例和架構圖

  2. 實戰案例分步教程
    📖?Dev.to 詳細教程

    • 從零開始的實現步驟


視頻資源

  1. 官方演示視頻
    ???YouTube 教程

    • 30分鐘實戰演示(Angular團隊錄制)

  2. 模塊聯邦深度解析
    ???Webpack 官方頻道

    • 底層原理講解


擴展工具

  1. 模塊聯邦工具庫
    📦?npm @angular-architects/module-federation-tools
    • 簡化動態加載的工具

  2. 微前端狀態管理方案
    📖?NgRx 集成指南
    • 跨應用狀態管理建議


常見問題

  1. 共享依賴解決方案
    ??Stack Overflow 熱門討論

    • 版本沖突處理方案

  2. 生產環境部署指南
    📖?Angular 部署文檔

    • 包含微前端部署注意事項


示例代碼庫

  1. 官方示例項目:可直接運行的完整項目
    💻?GitHub 代碼庫

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/web/83282.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/web/83282.shtml
    英文地址,請注明出處:http://en.pswp.cn/web/83282.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    無服務器架構的企業級應用深度解析:Serverless技術選型與成本模型

    ?? 目錄 引言:無服務器架構的興起無服務器架構核心概念主流Serverless平臺技術對比企業級應用場景分析成本模型深度分析私有化部署與云端服務對比決策框架構建最佳實踐與建議未來發展趨勢結論引言:無服務器架構的興起 在云計算快速發展的今天,無服務器架構(Serverless)…

    內網有貓和無線路由器,如何做端口映射從而實現外網訪問

    內網貓和無線路由器端口映射配置指南 端口映射&#xff08;Port Forwarding&#xff09;是將外網請求引導到內網特定設備和端口的技術&#xff0c;常用于遠程訪問、搭建服務器等場景。以下是配置方法&#xff1a; 基本原理 貓&#xff08;調制解調器&#xff09;&#xff1a…

    Spring boot應用監控集成

    Spring Boot應用監控集成記錄 背景 XScholar文獻下載應用基于Spring Boot構建&#xff0c;需要接入Prometheus監控系統。應用已部署并運行在服務器上&#xff0c;需要暴露metrics端點供Prometheus采集。 初始狀態 應用信息 框架: Spring Boot 2.x部署端口: 10089服務器: L…

    安寶特案例丨又一落地,Vuzix AR眼鏡助力亞馬遜英國倉庫智能化升級!

    Vuzix M400智能眼鏡近日落地亞馬遜&#xff08;英國&#xff09;倉庫&#xff0c;通過解放雙手、免提操作優化物流效率。 安寶特&VuzixAR智能眼鏡解決方案為亞馬遜倉庫提供實時決策支持、無縫對接員工-主管-企業管理系統&#xff0c;并加速了新員工培訓流程&#xff0c;優…

    ui框架-文件列表展示

    ui框架-文件列表展示 介紹 UI框架的文件列表展示組件&#xff0c;可以展示文件夾&#xff0c;支持列表展示和圖標展示模式。組件提供了豐富的功能和可配置選項&#xff0c;適用于文件管理、文件上傳等場景。 功能特性 支持列表模式和網格模式的切換展示支持文件和文件夾的層…

    使用QMediaPlayer開發音樂播放器

    編譯完成的程序下載:【免費】使用QMediaPlayer開發音樂播放器資源-CSDN文庫 完整源碼:使用QMediaPlayer開發音樂播放器源碼資源-CSDN文庫 需求分析: 1.本地音樂播放器 核心播放功能 支持常見音頻格式本地播放MP3、WAV、FLAC 等 2.播放控制:播放 / 暫停 / 停止 / 上一曲…

    Linux-07 ubuntu 的 chrome 啟動不了

    文章目錄 問題原因解決步驟一、卸載舊版chrome二、重新安裝chorme三、啟動不了&#xff0c;報錯如下四、啟動不了&#xff0c;解決如下 總結 問題原因 在應用中可以看到chrome&#xff0c;但是打不開(說明&#xff1a;原來的ubuntu系統出問題了&#xff0c;這個是備用的硬盤&a…

    【Redis】緩存雪崩、緩存擊穿、緩存穿透

    目錄 1、緩存雪崩【1】定義【2】原因【3】解決方案[1]差異化過期時間[2]多級緩存[3]熔斷降級[4]緩存永不過期異步更新 2、緩存擊穿【1】定義【2】原因【3】解決方案[1]互斥鎖[2]邏輯過期[3]熱點數據加載 3、緩存穿透【1】定義【2】原因【3】解決方案[1]緩存空對象[2]布隆過濾器…

    【論文閱讀筆記】萬花筒:用于異構多智能體強化學習的可學習掩碼

    摘要 在多智能體強化學習&#xff08;MARL&#xff09;中&#xff0c;通常采用參數共享來提高樣本效率。然而&#xff0c;全參數共享的流行方法通常會導致智能體之間的策略同質&#xff0c;這可能會限制從策略多樣性中獲得的性能優勢。為了解決這一關鍵限制&#xff0c;我們提出…

    vue2 , el-select 多選樹結構,可重名

    人家antd都支持&#xff0c;elementplus 也支持&#xff0c;vue2的沒有&#xff0c;很煩。 網上其實可以搜到各種的&#xff0c;不過大部分不支持重名&#xff0c;在刪除的時候可能會刪錯&#xff0c;比如樹結構1F的1樓啊&#xff0c;2F的1樓啊這種同時勾選的情況。。 可以全…

    golang循環變量捕獲問題??

    在 Go 語言中&#xff0c;當在循環中啟動協程&#xff08;goroutine&#xff09;時&#xff0c;如果在協程閉包中直接引用循環變量&#xff0c;可能會遇到一個常見的陷阱 - ??循環變量捕獲問題??。讓我詳細解釋一下&#xff1a; 問題背景 看這個代碼片段&#xff1a; fo…

    【一文看懂Spring循環依賴】Spring循環依賴:從陷阱破局到架構涅槃

    &#x1f32a;? Spring Boot循環依賴&#xff1a;從陷阱破局到架構涅槃 循環依賴如同莫比烏斯環上的螞蟻&#xff0c;看似前進卻永遠困在閉環中。本文將帶你拆解Spring中這一經典難題&#xff0c;從臨時救火到根治重構&#xff0c;構建無懈可擊的依賴體系。 &#x1f525; 一、…

    el-table封裝自動滾動表格(適用大屏)

    表格功能&#xff1a;自動滾動&#xff0c;鼠標移入停止滾動&#xff0c;移出繼續滾動。如果想加觸底加載新數據可以判斷 scrollWrap.scrollTop和maxScrollTop大小來加載數據&#xff0c;另寫邏輯。 <template><el-table ref"eltable" :data"tableDa…

    Eureka REST 相關接口

    可供非 Java 應用程序使用的 Eureka REST 操作。 appID 是應用程序的名稱&#xff0c;instanceID 是與實例關聯的唯一標識符。在 AWS 云中&#xff0c;instanceID 是實例的實例 ID&#xff1b;在其他數據中心&#xff0c;它是實例的主機名。 對于 XML/JSON&#xff0c;HTTP 的…

    DSP——時鐘樹講解

    配置任何外設的第一步都要看一下時鐘樹,下圖是DSP28377的時鐘樹: 由圖所示DSP28377由4個時鐘源,分別是INTOSC1、INTOSC2、XTAL、AUXCL INTOSC1:0M內部系統時鐘,備用時鐘,檢測到系統時鐘缺失自動連接到備用時鐘,也作為看門狗時鐘使用; INTOSC2:10M內部系統時鐘,復位…

    少量數據達到更好效果

    九坤團隊新作&#xff01;一條數據訓練AI超越上萬條數據 一 僅需一條無標簽數據和10步優化 九坤團隊訓練了13,440個大模型&#xff0c;發現熵最小化 (EM) 僅需一條無標簽數據和10步優化&#xff0c;就能實現與強化學習中使用成千上萬條數據和精心設計的獎勵機制所取得的性能提…

    html - <mark>標簽

    <mark> 標簽在HTML中用于高亮顯示文本&#xff0c;通常用于突出顯示某些重要的部分。它的默認樣式通常是背景色為黃色&#xff0c;但你可以通過CSS自定義其外觀。 1. 基本用法 <mark> 標簽用于標記文本的高亮顯示。它常用于搜索結果中&#xff0c;突出顯示匹配的…

    YOLOv8+ByteTrack:高精度人車過線統計系統搭建指南

    文章目錄 1. 引言2. YOLOv8簡介3. 過線統計原理4. 代碼實現4.1 環境準備4.2 基礎檢測代碼4.3 過線統計實現4.4 完整代碼示例5. 性能優化與改進5.1 多線程處理5.2 區域檢測優化5.3 使用ByteTrack改進跟蹤6. 實際應用中的挑戰與解決方案7. 總結與展望1. 引言 目標檢測是計算機視…

    20、React常用API和Hook索引

    這一小節中只給出一些API和Hook的索引&#xff0c;需要用到的時候可以去官網查詢&#xff0c;如無必要此處不列出詳細用法。React v1.19.1。 對Components的支持 以下是開發時通用的一些功能組件 APIdescription<Fragment>通常使用 <>…</> 代替&#xff0…

    Python爬蟲實戰:研究feedparser庫相關技術

    1. 引言 1.1 研究背景與意義 在當今信息爆炸的時代,互聯網上存在著海量的信息資源。RSS(Really Simple Syndication)作為一種標準化的信息聚合技術,被廣泛用于網站內容的發布和訂閱。通過 RSS,用戶可以方便地獲取網站更新的內容,而無需頻繁訪問各個網站。 然而,互聯網…