君威 發表於 2022-1-21 18:07:00

微前端-angular+qiankun+single-spa

<p>什么是微前端?</p>
<h2>主应用配置</h2>
<p>采用 Angular 作为主应用基座,接入不同的子Angular项目构建angular主应用基座</p>
<h3>使用angular cli生成angular项目</h3>
<div class="cnblogs_code">
<pre>ng new main</pre>
</div>
<h3>在主应用中安装 qiankun</h3>
<div class="cnblogs_code">
<pre>yarn add qiankun -D</pre>
</div>
<h3>将普通的angular项目改成主应用基座</h3>
<p>1 在layout页面添加微应用容器</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">nz-content </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="content"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="micro-app-container"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">router-outlet</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">router-outlet</span><span style="color: rgba(0, 0, 255, 1)">&gt;<br></span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">nz-content</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>2 注册微应用</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">export class AppComponent implements OnInit {
CONTAINER </span>= '#micro-app-container'<span style="color: rgba(0, 0, 0, 1)">;
microApps </span>=<span style="color: rgba(0, 0, 0, 1)"> [];
constructor(private router: Router, private startSvc: StartService) { }

ngOnInit(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
    const apps </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.startSvc.getConfig().MicroApps;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (apps &amp;&amp; apps.length &gt; 0<span style="color: rgba(0, 0, 0, 1)">) {
      apps.forEach((entry: any) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const paths </span>= `/micro/<span style="color: rgba(0, 0, 0, 1)">${entry.Path}`;
      const name </span>=<span style="color: rgba(0, 0, 0, 1)"> entry.Name;
      const app </span>=<span style="color: rgba(0, 0, 0, 1)"> {
          name: name,
          entry: paths,
          container: </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.CONTAINER,
          activeRule: () </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.canActive(`/${name}`);
<span style="color: rgba(0, 0, 0, 1)">          },
      };
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.microApps.push(app);
      });

      registerMicroApps(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.microApps);
    }
}

canActive(url: string) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.router.url.startsWith(url);
}

}</span></pre>
</div>
<p>3 添加微应用加载器MicroComponent,统一处理微应用资源引导,启用微应用</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">export class MicroComponent implements OnInit, AfterViewInit {
CONTAINER </span>= '#micro-app-container'<span style="color: rgba(0, 0, 0, 1)">;
constructor(private startSvc: StartService) { }

ngOnInit(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
}

ngAfterViewInit(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
    const apps </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.startSvc.getConfig().MicroApps;

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!window.qiankunStarted &amp;&amp; apps &amp;&amp; apps.length &gt; 0 &amp;&amp; document.getElementById(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.CONTAINER)) {
      window.qiankunStarted </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
      start({
      prefetch: </span>'all'<span style="color: rgba(0, 0, 0, 1)">,
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 指定部分特殊的动态加载的微应用资源(css/js) 不被 qiankun 劫持处理</span>
      excludeAssetFilter: (assetUrl: string) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
          </span><span style="color: rgba(0, 0, 255, 1)">if</span> (assetUrl.includes('/assets/'<span style="color: rgba(0, 0, 0, 1)">)) {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
          }
      },
      });
    }
}
}</span></pre>
</div>
<p>&nbsp;</p>
<p>4&nbsp;在主应用的某个路由页面加载微应用&nbsp;</p>
<p>注册微应用时仅需要在app-routing.ts添加相应的path即可:<span class="ne-viewer-b-filler"><br></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
      path: </span>'project'<span style="color: rgba(0, 0, 0, 1)">,
      component: MicroComponent,
      children: [{ path: </span>'**'<span style="color: rgba(0, 0, 0, 1)">, component: EmptyComponent }],
      },</span></pre>
</div>
<p>配置开发环境proxy<span class="ne-viewer-b-filler"><br></span>在开发环境中,主应用和微应用分别运行在两个不同的进程(网站)中。调试时应在proxy.conf.js 配置代理<span class="ne-viewer-b-filler"><br></span></p>
<div class="ne-card-container">
<div class="ne-code ne-codeblock ne-code-viewer ne-codeblock-height-limit" data-codeblock-mode="json">
<div class="ne-embed-nav" data-testid="ne-embed-nav">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
    context: [</span>'/micro/project'<span style="color: rgba(0, 0, 0, 1)">],
    target: </span>'http://localhost:4200', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">微应用地址</span>
    secure: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">,
},</span></pre>
</div>
<p>&nbsp;</p>
<h2><span class="ne-codeblock-mode-name"><span class="ne-codeblock-mode-name">微应用配置</span></span></h2>
</div>
<div class="ne-embed-nav" data-testid="ne-embed-nav">&nbsp;参考&nbsp;<span class="ne-codeblock-mode-name"><span class="ne-codeblock-mode-name"><span class="ne-codeblock-mode-name">angular微应用&nbsp;</span></span></span></div>
<div class="ne-embed-nav" data-testid="ne-embed-nav">
<h3><span class="ne-codeblock-mode-name"><span class="ne-codeblock-mode-name"><span class="ne-codeblock-mode-name">1&nbsp;</span></span></span>使用angular cli生成angular项目</h3>
<div class="cnblogs_code">
<pre>ng new micro</pre>
</div>
<h3>2 在微应用中安装&nbsp;<code class="ne-code"><span class="ne-text">single-spa-angular</span></code><span class="ne-text">&nbsp;插件来配置<span class="ne-text">微应用&nbsp;参考&nbsp;single-spa-angular 的官网&nbsp;和&nbsp;angular demo&nbsp;</span></span></h3>
<div class="cnblogs_code">
<pre>ng add single-spa-angular</pre>
</div>
<p><img src="https://img2022.cnblogs.com/blog/1374003/202201/1374003-20220121163833919-2039675626.png"></p>
<p><span class="ne-text">angular.json: builder改成了自定义Webpack构建器 "builder": "@angular-builders/custom-webpack:browser";</span><span class="ne-text">主文件入口改成了<code class="ne-code"><span class="ne-text">main.single-spa.ts</span></code><span class="ne-text">。</span></span></p>
</div>
<p>tsconfig.app.json: 解决&nbsp;<code>zone.js</code>&nbsp;的问题:1在<strong>父应用</strong>引入&nbsp;<code>zone.js</code>,需要在&nbsp;<code>import qiankun</code>&nbsp;之前引入。2将微应用的&nbsp;<code>src/polyfills.ts</code>&nbsp;里面的引入&nbsp;<code>zone.js</code>&nbsp;代码删掉。</p>
<p class="ne-embed-nav" data-testid="ne-embed-nav"><span class="ne-text">新增<code class="ne-code"><span class="ne-text">extra-webpack.config.js</span></code><span class="ne-text">,主要作用是<span class="ne-text">允许开发环境跨域和&nbsp;<code class="ne-code"><span class="ne-text">umd</span></code><span class="ne-text">&nbsp;打包,<span class="ne-text">让主应用能正确识别微应用暴露出来的一些信息<span class="ne-text">。</span></span></span></span></span></span></p>
<p class="ne-embed-nav" data-testid="ne-embed-nav"><span class="ne-text">新增的<span class="ne-text">main.single-spa.ts,<span class="ne-text">导出&nbsp;<code class="ne-code"><span class="ne-text">bootstrap</span></code><span class="ne-text">、<code class="ne-code"><span class="ne-text">mount</span></code><span class="ne-text">、<code class="ne-code"><span class="ne-text">unmount</span></code><span class="ne-text">&nbsp;三个生命周期钩子,以供主应用在适当的时机调用。</span></span></span></span></span></span></p>
<div class="ne-embed-nav" data-testid="ne-embed-nav">
<p><span class="ne-text">新增emptyRouteComponet,为应用间跳转做过度。</span><span class="ne-text">asset-url.ts,动态加载子应用内assets时,能正确引入assets资源。</span></p>
<p>&nbsp;</p>
<h3>3 修改angular.json</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">architect</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
      </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">build</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
          </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">builder</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">@angular-builders/custom-webpack:browser</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
          </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">options</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">baseHref</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/micro/project/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">deployUrl</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/micro/project/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">outputPath</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">wwwroot/micro/project</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">index</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/index.html</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">main</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/main.single-spa.ts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">polyfills</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/polyfills.ts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tsConfig</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tsconfig.app.json</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">aot</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">assets</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/favicon.ico</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/assets</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            ],
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">styles</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/styles.less</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            ],
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">scripts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [],
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">customWebpackConfig</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">path</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">extra-webpack.config.js</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">libraryName</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">micro</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
            </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">libraryTarget</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">umd</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            }
          },<br>          ...<br>      }<br>      ...<br>}</span></pre>
</div>
<p>&nbsp;</p>
<p>4和5不需要,也可以</p>
<h3><span style="color: rgba(192, 192, 192, 1)">4&nbsp;<span class="ne-text">修改public-path</span></span></h3>
<div class="lake-content">
<p id="u17479312" class="ne-p"><span class="ne-text" style="color: rgba(192, 192, 192, 1)">在入口文件main.micro.ts修改<span class="ne-text">__webpack_public_path__&nbsp;</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(192, 192, 192, 1)">__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ + 'project/'</span></pre>
</div>
<div class="ne-quote">
<p id="ua766c948" class="ne-p"><span class="ne-text" style="color: rgba(192, 192, 192, 1)">需在typing.d.ts文件声明</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(192, 192, 192, 1)">declare var __webpack_public_path__;

interface Window {
__POWERED_BY_QIANKUN__: any;
__INJECTED_PUBLIC_PATH_BY_QIANKUN__: any;
}</span></pre>
</div>
</div>
</div>
<h3><span style="color: rgba(192, 192, 192, 1)">5&nbsp;<span class="ne-text">设置APP_BASE_HREF</span></span></h3>
<div class="lake-content">
<div class="ne-quote">
<p id="fa3eb189a134b2c56d7e56258e12fc56" class="ne-p"><span class="ne-text" style="color: rgba(192, 192, 192, 1)">当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。</span></p>
</div>
<p id="fb5d2e8813e22010300d4fbf9a64cecc" class="ne-p"><span class="ne-text" style="color: rgba(192, 192, 192, 1)">为使微应用能够正确接入基座,应在<span class="ne-text">root.module.ts<span class="ne-text">中设置<code class="ne-code"><span class="ne-text">APP_BASE_HREF</span></code><span class="ne-text"> 。&nbsp;&nbsp;</span></span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(192, 192, 192, 1)">providers: [
    { provide: APP_BASE_HREF, useValue: window.__POWERED_BY_QIANKUN__ ? '/' : '/micro/' },
],</span></pre>
</div>
<h3>&nbsp;</h3>
<h3>6 路由配置</h3>
<div class="lake-content">
<p id="85be2226ef67a266f72e90468e59433f" class="ne-p"><span class="ne-text">业务相关路由初始化时,第一级路由的path应当以微应用编码命名,并在children里追加下级路由:</span></p>
<div class="lake-content"><span class="ne-text">EmptyRouteComponent,为应用间跳转做过度,解决 cannot match url 的报错问题</span></div>
</div>
<div class="cnblogs_code">
<pre>const routes: Routes =<span style="color: rgba(0, 0, 0, 1)"> [
{
    path: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">project</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> canActivateChild: ,</span>
<span style="color: rgba(0, 0, 0, 1)">    children: [
      { path: </span><span style="color: rgba(128, 0, 0, 1)">''</span>, redirectTo: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">week</span><span style="color: rgba(128, 0, 0, 1)">'</span>, pathMatch: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">full</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> },</span></pre>
<div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; { path: 'apply', component: ApplyComponent },</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; { path: 'statistics', component: StatisticsComponent },</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; { path: 'setting', component: SettingComponent },</div>
</div>
<pre><span style="color: rgba(0, 0, 0, 1)">      { path: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">**</span><span style="color: rgba(128, 0, 0, 1)">'</span>, redirectTo: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/404</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> },
    ],
},
{ path: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">**</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, component: EmptyRouteComponent },
];

@NgModule({
imports: ,
exports: ,
})</span></pre>
</div>
<p>&nbsp;</p>
</div>
<h3>7 差异化app-root</h3>
<p>为了防止主应用或其他微应用也为 angular 时,&lt;app-root&gt;&lt;/app-root&gt; 会冲突的问题,需要为&lt;app-root&gt; 加上唯一的 id,并以当前应用的业务模块编码命名。</p>
<p>src/index.html :</p>
<div class="cnblogs_code">
<pre>- &lt;app-root&gt;&lt;/app-root&gt;
+ &lt;app-root <span style="color: rgba(0, 0, 255, 1)">id</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">project</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/app-root&gt;</pre>
</div>
<p>src/app/root.component.ts :</p>
<div class="ne-card-container">
<div class="ne-code ne-codeblock ne-code-viewer ne-codeblock-height-limit" data-codeblock-mode="typescript">
<div class="ne-codeblock-inner">
<div class="CodeMirror cm-s-default">
<div class="CodeMirror-scroll">
<div class="CodeMirror-sizer">
<div class="CodeMirror-lines">
<div class="CodeMirror-code">
<div class="cnblogs_code">
<pre>- selector: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">app-root</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
</span>+ selector: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">#project app-root</span><span style="color: rgba(128, 0, 0, 1)">'</span>,</pre>
</div>
<p>&nbsp;</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
</div>
</div><br><br>
来源:https://www.cnblogs.com/tingying/p/15829957.html
頁: [1]
查看完整版本: 微前端-angular+qiankun+single-spa