Angular v17:如何将现有项目嵌入新项目并通过独立路由跨文件夹访问?
Angular 17 独立项目嵌入售卖方案实现方法
针对你的需求,有三种可行的实现方式,均能满足两个项目无需同文件夹的要求:
1. 将售卖项目打包为Web Component(Angular Elements)
这是Angular官方支持的组件化方案,可把现有项目封装成可复用的自定义元素嵌入新项目:
- 在售卖项目安装依赖:
npm install @angular/elements @webcomponents/custom-elements - 修改根组件配置,将其注册为Web Component(以Angular 17独立组件为例):
import { createCustomElement } from '@angular/elements'; import { AppComponent } from './app.component'; import { Injector } from '@angular/core'; export class AppModule { constructor(private injector: Injector) { const appElement = createCustomElement(AppComponent, { injector }); customElements.define('sold-angular-app', appElement); } ngDoBootstrap() {} } - 打包售卖项目:执行
ng build --output-hashing none,从dist目录提取生成的main.js、polyfills.js(按需)和样式文件。 - 在新项目中,将这些文件放入
assets目录,然后在专属路由页面:- 在组件
ngOnInit或index.html中引入JS/CSS文件 - 模板中直接使用自定义元素:
<sold-angular-app></sold-angular-app>
- 在组件
- 样式隔离处理:可在售卖项目根组件元数据中设置
encapsulation: ViewEncapsulation.ShadowDom,避免全局样式冲突。
2. 使用iframe嵌入部署好的售卖项目
这是轻量化快速实现方案:
- 将售卖项目独立部署到服务器(支持独立域名、子域名或同域名子路径)
- 在新项目专属路由页面模板中添加iframe标签:
<iframe src="https://your-sold-app-domain.com" width="100%" height="100vh" frameborder="0" ></iframe> - 登录状态同步:通过
postMessageAPI传递认证信息,需验证消息来源域名保障安全:
新项目发送代码:
售卖项目接收代码:const iframe = document.querySelector('iframe'); iframe?.contentWindow?.postMessage({ type: 'AUTH_TOKEN', token: userToken }, 'https://your-sold-app-domain.com');window.addEventListener('message', (event) => { if (event.origin !== 'https://your-new-project-domain.com') return; if (event.data.type === 'AUTH_TOKEN') { // 验证token并处理登录逻辑 } });
3. 使用Module Federation实现微前端集成
该方案可实现无缝路由集成,用户体验接近单应用,Angular 17原生支持:
- 在售卖项目配置Module Federation:修改
angular.json,在architect.build.options中添加:"options": { "mfeType": "remote", "exposes": { "./App": "src/app/app.component.ts", "./Routes": "src/app/app.routes.ts" }, "port": 4201 } - 在新项目配置Module Federation作为宿主:修改
angular.json,添加:"options": { "mfeType": "host", "remotes": { "soldApp": "http://localhost:4201/remoteEntry.js" } } - 在新项目路由中加载售卖项目的路由:
import { loadRemoteModule } from '@angular-architects/module-federation'; const routes: Routes = [ // 其他路由 { path: 'sold-app', loadChildren: () => loadRemoteModule({ type: 'module', remoteEntry: 'http://localhost:4201/remoteEntry.js', exposedModule: './Routes' }).then(m => m.routes) } ]; - 两个项目可独立部署,宿主通过远程入口文件加载售卖项目模块,无需同文件夹。
内容的提问来源于stack exchange,提问作者JSmith
相关产品推荐
相关产品推荐

