从现有项目构建角度元素

Ste*_*fan 13 angular-cli angular angular-elements

我们有一个现有的Angular 8项目,其中包含许多常用组件(例如custom datepickers, numeric inputs, ...)。该项目本身是一个标准的Angular应用程序。

我们希望将其中一些组件提取为Angular元素,以便可以在其他Angular应用程序甚至与Angular不相关的其他项目中使用。

是否可以通过仅在生成的JavaScript文件中包含特定于单个Angular元素的代码的方式构建项目?

我需要的是这样的: ng build --element myDatePicker

这应该myDatePicker-Element只为所有具有所有所需依赖项的项目生成所有JavaScript文件,而无需从项目中获取任何其他代码(如other components, modules, ...)。

使用时,整个应用仍应正常构建ng build

Vid*_*del 6

为了组件的可重用性,您可以在“公共”npm 依赖项中提取您的组件。Angular 文档可以在这里找到:https : //angular.io/guide/creating-libraries

请记住,您必须构建您的库项目,然后在 npm 注册表(公共注册表或私有注册表)上发布包以用作依赖项。

要在 Angular 之外使用您的 Angular 组件,您可以使用 Angular Elements 将您的组件转换为标准的 WebComponents ( https://angular.io/guide/elements )。

请记住,您仍然需要某种构建管道来将您的 Angular 代码转换为 JS。


Din*_*ino 5

我建议您看一下Angular Elements,更具体地说是createCustomElement。这将帮助您准确实现所需的功能。

我可以给您一个简短的指南,说明您可以做什么。

例如我的Github回购

1)首先是安装@ angular / elements

npm i @angular/elements --save

2)此步骤包括修改app.module.ts。如果您只想构建一组选定的组件(自定义日期选择器,数字输入等),则必须暂时删除bootstrap: [ ]并将其替换为entryComponents: [ ]。在entryComponents中,您将放置要构建的定制组件。

entryComponents: [MyCustomDatePickerComponent, CustomButtonComponent]
Run Code Online (Sandbox Code Playgroud)

3)现在是时候告诉Angular引导您的自定义组件了。您还必须为自定义组件定义选择器。您将在注入它们的任何其他应用程序中使用该选择器调用它们。例如:<my-button-element></my-button-element>

export class AppModule {

  constructor(private injector: Injector) {}

  ngDoBootstrap() {
    const el = createCustomElement(CustomButtonComponent,
      { injector: this.injector });
    customElements.define('my-button-element', el);
    const el2 = createCustomElement(MyCustomDatePickerComponent,
      { injector: this.injector });
    customElements.define('custom-date-picker', el2);
  }
}
Run Code Online (Sandbox Code Playgroud)

4)构建组件-如果运行,ng build --prod您将获得多个文件。我们希望将这些文件合并为一个,以便更轻松地使用和注入已构建的自定义元素。有两个软件包可以帮助我们做到这一点。npm install --save-dev concat fs-extra

elements-build.jsroot您的应用程序中创建一个in 并将其粘贴。(这将在合并一个构建输出.js.css文件,并把它们放在root/elements文件夹中。

const concat = require('concat');
const fs = require('fs-extra');

(async function build() {
  // Instead of /CustomElements/ put your project name - just check a dist folder to see how its formatted and make it that way
  const files = [
    './dist/CustomElements/runtime-es2015.js',
    './dist/CustomElements/polyfills-es2015.js',
    './dist/CustomElements/main-es2015.js'
  ];

  await fs.ensureDir('elements');
  await concat(files, 'elements/myCustomElements.js');
  await fs.copyFile(
    './dist/CustomElements/styles.css',
    'elements/styles.css'
  );
})();
Run Code Online (Sandbox Code Playgroud)

5)在您的package.json中添加

"build:elements": "ng build --prod --output-hashing none && node elements-build.js",
Run Code Online (Sandbox Code Playgroud)

6)就这样。您已经构建了自定义元素,并且可以在其他Angular应用程序甚至非Angular应用程序中的任何地方重用它们。唯一要做的就是导入.js.css刚创建的。您甚至可以像往常一样使用Input()和Output()。

<custom-date-picker dateTitle="My Date Title"></custom-date-picker>

注意: 如果您决定将其导入到另一个Angular应用程序中,则可能会遇到问题,zone.js因为它将被导入两次。解决方案是仅将其导入一次(无论是从核心应用程序还是自定义元素)。

  • 这并不能真正解决我的问题。我知道如何创建角度元素。我的问题是我想用这个自定义组件作为起点进行构建。这将导致一个仅包含元素和所需依赖项的包。目前我能看到的唯一方法是为每个组件创建一个自己的 Angular-Library。 (3认同)

Byt*_*ech -1

You can create and publish new libraries to extend Angular functionality. If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.

The command for generating a library is ng generate library my-lib

库通常包含可重用的代码,这些代码定义了组件、服务和其他 Angular 工件(管道、指令等),您只需将其导入到项目中即可。库被打包到 npm 包中以供发布和共享,并且该包还可以包含原理图,提供直接在项目中生成或转换代码的说明,就像 CLI 使用 nggenerate 组件创建通用骨架应用程序一样。例如,与库结合的原理图可以为 Angular CLI 提供生成该库中定义的特定组件所需的信息。

来源: https: //angular.io/guide/creating-libraries