Angular 9 Elements:如何创建一个独立的 WebComponent(包含所有依赖项)?

Posted

技术标签:

【中文标题】Angular 9 Elements:如何创建一个独立的 WebComponent(包含所有依赖项)?【英文标题】:Angular 9 Elements: how to create a standalone WebComponent (with all the dependencies)? 【发布时间】:2020-06-22 07:35:58 【问题描述】:

我正在尝试使用 Angular 9WebComponents 设计一个基于 Micro Frontends 的新应用程序。 我想通过 WebComponents 实现的主要目标是让不同的团队能够独立工作,随时部署他们的更新,并且让主包装器只需下载相应的自包含包并将其注入包装页面。

目前我不需要处理不同的框架,但我只需要在它们之间有非常低耦合,无论是依赖关系(每个WebComponent应该自己带来自己的依赖关系,目前允许的 Polyfills 和 Runtime 例外)和部署(只需部署/公开 WebComponent 捆绑包并通过 GET API 将其注入包装器)。 我想到的架构如下:

    UI:这是所有其他 WebComponents 的包装器 DashboardOne-UI:注册为 WebComponent 的仪表板 DashboardTwo-UI:注册为 WebComponent 的仪表板

我在网上找到的WebComponents的例子都是非常基础的;我的意思是他们只使用标准的 html 元素(按钮、段落、...),因此没有依赖项可以合并到输出包中。 就我而言,DashboardOne-UI 依赖于 Prime-NGPrime-Icons,我会避免在 UI 上也安装此类依赖项.

为了构建 DashboardOne-UI 并提供输出文件,我通过运行以下命令来使用 NGX-Build-PlusHTTP-Server: p>

"scripts": 
    "start": "http-server dist/DashboardOne-UI/ --port 8084",
    "build": "ng build --prod --single-bundle"

构建后,dist文件夹包含:

这是index.html的内容:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>OrganizationUI</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <organization-dashboard></organization-dashboard>
    <script src="polyfills.js" defer></script>
    <script src="scripts.js" defer></script>
    <script src="polyfill-webcomp-es5.js" defer></script>
    <script src="polyfill-webcomp.js" defer></script>
    <script src="main.js" defer></script>
  </body>
</html>

通过运行启动脚本,我可以让 WebComponent 在浏览器中按预期工作,但是当我在 UI 应用程序中仅注入 ma​​in.js 脚本时它无法获取所有字体和样式:

我发现避免对包装 UI 产生此类依赖的唯一方法是使 DashboardOne WebComponent'css 指向 NPM 代替本地 node_modules,使用:

@import url("https://unpkg.com/primeicons@2.0.0/primeicons.css");
@import url("https://unpkg.com/primeng@9.0.0/resources/primeng.min.css");
@import url("https://unpkg.com/primeng@9.0.0/resources/themes/nova-light/theme.css");
@import url("https://unpkg.com/bootstrap@4.4.1/dist/css/bootstrap.min.css");

代替:

@import url("~primeicons/primeicons.css");
@import url("~primeng/resources/primeng.min.css");
@import url("~primeng/resources/themes/nova-light/theme.css");
@import url("~bootstrap/dist/css/bootstrap.min.css");

这种方法的问题是我需要在两个地方处理依赖关系,css 和 package.json。 有没有更好的方法在 Angular 9 中构建自包含的 WebComponents,这样我只需要在包装 UI 应用程序中导入单个 JS 文件,而不关心 WebComponents 的依赖关系?

【问题讨论】:

【参考方案1】:

我刚刚发现,一种可能的更好解决方案的方法是提供

ng build

带有部署 URL 的路径(更多信息 here):

"scripts": 
  "start": "http-server dist/DashboardOne-UI/ --port 8084",
  "build": "ng build --single-bundle --deploy-url http://localhost:8084/"

通过这种方式,DashboardOne-UI web-component 元素,一旦注入到 UI 包装器中,将指向它自己的服务器,所有需要的资源都可以存放在该服务器上找到了。

【讨论】:

你能分享更多关于使用 Angular 9 创建 Web 组件的细节吗?将不胜感激。

以上是关于Angular 9 Elements:如何创建一个独立的 WebComponent(包含所有依赖项)?的主要内容,如果未能解决你的问题,请参考以下文章

Angular Karma 使用 CUSTOM_ELEMENTS_SCHEMA 测试超时测试 AppComponent

Angular 指令创建重复元素

如何在 Angular 9 中将 HTML 页面拆分为 A4 大小

测试 Angular 2 应用程序中的“CUSTOM_ELEMENTS_SCHEMA”错误

[Angular 2] Using ng-for to repeat template elements

如何在反应式表单中设置模型数据,Angular 9