如何在常规 Angular 组件和 Angular 元素之间共享代码?

How to share code between a regular Angular component and an Angular Element?

假设我将使用 nx 来在单存储库中的不同站点之间共享库。 我有两个网站:

站点 1 有一个 helloWorld Angular 组件。 在站点 2 上,我想使用 helloWorld 组件,但作为由 Angular 元素创建的 Web 组件。所有 Angular 组件和元素都应存储在共享的外部 nx 库中。

有没有办法在常规 Angular 组件和 Angular 元素之间共享代码?或者,将常规组件嵌套在元素中?

几步之内就有一个可能的解决方案。

1。生成库

第一步是生成要存储共享自定义元素的 nx 库。
nx g lib custom-elements

angular.json 中为这个库添加构建步骤,例如:

        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/libs/custom-elements",
            "index": "libs/custom-elements/src/lib/index.html",
            "main": "libs/custom-elements/src/lib/main.ts",
            "tsConfig": "libs/custom-elements/tsconfig.lib.json",
            "aot": true,
            "assets": [],
            "styles": [],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [],
              "optimization": true,
              "outputHashing": "none",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        },

这里的主要部分是"builder": "@angular-devkit/build-angular:browser",,因为我们后面要用到这个库构建的文件。 也不要忘记添加空 index.html 文件。

2。将您的 angular 组件标记为自定义元素

首先,添加angular个元素npm install @angular/elements
然后使用 createCustomElement:

标记您要共享的组件

@NgModule({
   imports: [BrowserModule],
   entryComponents: [SomeComponent],
})
export class SharedComponentsModule {
   constructor(readonly injector: Injector) {
       const ngElement = createCustomElement(SomeComponent, {
           injector,
       });

       customElements.define('some-component', ngElement);
   }

   ngDoBootstrap() {}
}

3。构建库并将必要的脚本添加到静态页面

运行nx build custom-elements。您将获得 dist/libs/custom-elements 中的所有文件。您现在可以将它们添加到任何页面并使用自定义元素!

工作示例

我在这里创建了一个工作示例https://github.com/nickbullock/share-custom-elements-between-angular-and-static-app

如何 运行 angular 应用程序:npm start
如何 运行 静态应用程序:npm run app2:serve

额外阅读

https://indepth.dev/posts/1116/angular-web-components-a-complete-guide

https://medium.com/angular-in-depth/how-to-compile-your-angular-components-library-into-web-components-47ff0ac73bd7

Is there a way to share code between the regular Angular Component and the Angular Element?

是的,这就是我们使用图书馆的原因。 库不仅仅是在 Nx 中共享代码的一种方式。它们对于将代码分解成具有明确定义的 public API 的小单元也很有用。 NX 建议使用 small number of library types.

根据angular.io, Angular elements are Angular components packaged as custom elements (also called Web Components), so what you need is Nx Plugin for Web which contains generators for managing Web Component applications and libraries within an Nx workspace. You may need the helpful instructions inside Create Libs in Angular using NX满足您的目的。

Is there a way to nest the regular component inside the element?

是的,因为 Angular 允许我们将可重用的逻辑放入单独的单元中。