单页 angular 元素中开发的多个自定义元素
Multiple Custom element developed in angular element in single page
我在不同的 Angular 元素项目中开发了 2 个自定义元素,当我尝试在单个 html 中使用它们时,出现错误 "Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry"
如何按照这个link发展https://medium.freecodecamp.org/how-to-create-angular-6-custom-elements-web-components-c88814dc6e0a
我知道它与加载两次打包在两个自定义元素中的库有关。如何解决?
谢谢
问题: Elements 打包了整个 Angular 并将其作为单个 JS 文件弹出。当其中两个 运行 在一个页面上时,会发生一些可怕而奇怪的冲突,这些冲突可能会或可能不会影响您的元素的行为方式(很可能会)。
解决方案: 我能够让 2 angular 元素在单个页面上完美工作的唯一方法是将它们组合到一个应用程序中。它们仍然是单独的元素,这意味着您可以在页面的任何位置独立包含这些自定义标签。
您仍然可以按照步骤构建自定义元素,但在您的 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 中工作,但不能同时在两者中工作。我的元素也不是简单的元素,它们有很多工作部分(bootstrap 模态、农业网格等)。希望这对以后的人有所帮助。
我遇到了同样的问题,但发现了一个略有不同的解决方案,该解决方案可以减少代码量,尤其是当您有 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>
我找到了 here 替代方法,它允许我在另一个 angular 项目中有两个单独的 angular 网络组件。我在 MacOs
上做
在您的网络组件上(它是单独的 angular 项目 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
I add/edit 键中:
"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
的方式相同 - 在您的 angular 项目中,您可以通过 [=22 将两者添加到您的 index.html
=]
<head>
...
<script src="./assets/web-components/myComponent.js" type="text/javascript"></script>
<script src="./assets/web-components/myComponent2.js" type="text/javascript"></script>
...
</head>
两者应该同时工作
我在不同的 Angular 元素项目中开发了 2 个自定义元素,当我尝试在单个 html 中使用它们时,出现错误 "Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry" 如何按照这个link发展https://medium.freecodecamp.org/how-to-create-angular-6-custom-elements-web-components-c88814dc6e0a
我知道它与加载两次打包在两个自定义元素中的库有关。如何解决?
谢谢
问题: Elements 打包了整个 Angular 并将其作为单个 JS 文件弹出。当其中两个 运行 在一个页面上时,会发生一些可怕而奇怪的冲突,这些冲突可能会或可能不会影响您的元素的行为方式(很可能会)。
解决方案: 我能够让 2 angular 元素在单个页面上完美工作的唯一方法是将它们组合到一个应用程序中。它们仍然是单独的元素,这意味着您可以在页面的任何位置独立包含这些自定义标签。
您仍然可以按照步骤构建自定义元素,但在您的 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 中工作,但不能同时在两者中工作。我的元素也不是简单的元素,它们有很多工作部分(bootstrap 模态、农业网格等)。希望这对以后的人有所帮助。
我遇到了同样的问题,但发现了一个略有不同的解决方案,该解决方案可以减少代码量,尤其是当您有 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>
我找到了 here 替代方法,它允许我在另一个 angular 项目中有两个单独的 angular 网络组件。我在 MacOs
上做在您的网络组件上(它是单独的 angular 项目 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
I add/edit 键中:
"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
的方式相同 - 在您的 angular 项目中,您可以通过 [=22 将两者添加到您的 index.html
=]
<head>
...
<script src="./assets/web-components/myComponent.js" type="text/javascript"></script>
<script src="./assets/web-components/myComponent2.js" type="text/javascript"></script>
...
</head>
两者应该同时工作