2

我在不同的 Angular 元素项目中开发了 2 个自定义元素,当我尝试在单个 html 中使用它们时,出现错误“无法在 'CustomElementRegistry' 上执行 'define':此名称已与此注册表一起使用”如何点击此链接开发https://medium.freecodecamp.org/how-to-create-angular-6-custom-elements-web-components-c88814dc6e0a

我知道它与加载两个自定义元素中两次打包的库有关。如何解决这个问题?

谢谢

4

3 回答 3

3

我在这里找到了另一种方法,它允许我在另一个 Angular 项目中拥有两个单独的 Angular Web 组件。我在 MacO 上做

在您的网络组件(这是单独的角度项目my-component)上运行以下命令

npm install ngx-build-plus -S
ng update ngx-build-plus --force
ng add ngx-build-plus
ng g ngx-build-plus:wc-polyfill
ng g ngx-build-plus:externals

(这将在您的项目目录中创建文件webpack.externals.js)然后在我package.json的键中scripts添加/编辑键:

"build:my-componente:externals": "ng build --output-hashing none --extra-webpack-config webpack.externals.js --prod --single-bundle true --project my-component && cat dist/my-component/polyfill-webcomp-es5.js dist/my-component/polyfills-es5.js dist/my-component/scripts.js dist/my-component/main-es5.js > dist/myComponent.js"

现在我通过以下方式构建 Web 组件:

npm run build:my-componente:externals

这将创建文件dist/myComponent.js- 以与您构建相同的方式myComponent2.js- 在您的角度项目中,您可以将两者都添加到您index.html的 by

<head>
...
  <script src="./assets/web-components/myComponent.js" type="text/javascript"></script>
  <script src="./assets/web-components/myComponent2.js" type="text/javascript"></script>
...
</head>

两者都应该同时工作

于 2020-12-08T19:22:39.540 回答
3

问题: Elements 将整个 Angular 打包,并将其作为单个 JS 文件输出。当其中两个在一个页面上运行时,会发生一些可怕而奇怪的冲突,这些冲突可能会也可能不会影响您的元素的行为方式(很可能会)。

解决方案:我能够让 2 个角度元素在单个页面上完美工作的唯一方法是将它们组合到一个应用程序中。它们仍然是独立的元素,这意味着您可以在页面上的任何位置独立地包含这些自定义标签。

您仍然可以按照步骤构建自定义元素,但在您的app.module.ts文件中添加您想要定义的任何其他元素:

  ngDoBootstrap() {
    const ele1= createCustomElement(ComponentOne, { injector: this.injector });
    customElements.define('my-ele-one', ele1);

    const ele2= createCustomElement(ComponentTwo, { injector: this.injector });
    customElements.define('my-ele-two', ele2);

    const ele3= createCustomElement(ComponentThree, { injector: this.injector });
    customElements.define('my-ele-three', ele3);

    ....
  }

你的 HTML 可能看起来像

<h1> My Elements </h1>

<my-ele-one></my-ele-one>

<p>What a cool element!</p>

<my-ele-two></my-ele-two>

<div class='turtle'>
 <p><my-ele-three></my-ele-three></p>
</div>

这甚至可以减少您的整体页面开销,因为现在您不会有两个完整的应用程序被拉入。

我可能花了 50 多个小时试图配置两个单独的 Angular Elements 应用程序以协同工作,但无济于事。我确实需要支持所有浏览器,这绝对是一个重要因素,因为我可以让某些配置在 Chrome 或 IE 中运行,但不能同时在两者中运行。我的元素也不是简单的元素,它们有很多工作部分(引导模式、ag-grids 等)。希望这对将来的某人有所帮助。

于 2019-04-10T19:25:56.490 回答
0

我遇到了同样的问题,但发现了一个稍微不同的解决方案,导致代码更少,特别是如果您有 2 个以上的自定义元素。我希望我写了它,但我将这个解决方案归功于 fireship.io 的 Jeff Delany。

export class AppModule {
  constructor(private injector: Injector) {}

ngDoBootstrap() {
      const elements: any[] = [
        [AwesomeComponent, 'custom-awesome'],
        [CoolComponent, 'custom-cool']
      ];

      for (const [component, name] of elements) {
        const htmlElement = createCustomElement(
          component, {injector: this.injector});
        customElements.define(name, htmlElement);
      }
    }
}

index.html 可能看起来像这样:

<h1>Multiple Custom Elements</h1>

<div><custom-awesome></custom-awesome></div>
<div><custom-cool></custom-cool></div>

<p>Hope this helps you out</p>
于 2020-06-23T18:58:38.243 回答