未捕获的 DOMException:无法在"自定义元素注册表"上执行"定义":此名称已用于此注册表



未捕获的DOMException:未能在"CustomElementRegistry"上执行"define":此名称已与此注册表一起使用在http://127.0.0.1:8000/components/@聚合物/聚合物/lib/elements/dom模块js:175:16

尝试删除节点模块和程序包锁定,但重新安装失败。

此错误是由于正在注册的自定义元素标记名称已注册;要修复此问题,只需检查此名称的元素是否尚未注册。这个示例解决方案检查某个东西是否已经使用现有的API注册,如果没有,则注册给定的Class(继承/扩展HTMLElement——在某个时候):

customElements.get('the-element') || customElements.define('the-element', HTMLTheElement);

有关API的更多信息,请参阅https://developer.mozilla.org/docs/Web/API/CustomElementRegistry

大多数/成熟的库都解决了这个问题,而那些没有解决这个问题的库,或者被包和构建过程的复杂性弄得一团糟的库,可能会弹出这个问题;在大多数情况下,要么更新到当前版本,要么迁移到Lit(https://lit.dev)或者以某种方式修补问题提供了解决方案的途径;注意,更简单的解决方案更容易维护——可以从npm、polymer与原始问题中的实际错误的合并中看出;Polymer项目变成了lit-html和LitElement,最近更名为";Lit";(仍然包括这些发光的东西)。从专业角度讲,我正在从npm和Nodejs迁移到Deno,目的是普遍解决与npm和工具不安全性和复杂性相关的许多问题,然而,这个答案提供了一个更直接的解决方案(了解问题并直接修复,或者更新到相关的最新解决方案,其中以某种方式包括这一点)。

好吧,这对我来说很有效,没有Typescript警告,

if (!customElements.get('the-element')) { customElements.define('the-element', HTMLTheElement); }

希望有人会发现这个有用。

干杯。

使用上面的答案是不明智的。你希望它失败!原因是您的NPM应该删除重复的包,因此您多次看到某个组件在自定义元素注册表中被定义是一个关键错误,您需要调试为什么同一组件被多次注册。

如何调试,简而言之,转到浏览器,检查元素,网络选项卡,刷新,找出哪些文件都在注册同一个元素。然后签入启动器以查看哪些文件正在加载这些文件。然后,您可以更好地了解为什么您的应用程序没有将同一导入解析到一个位置(您的重复数据消除依赖项)。

你可能面临这个问题的一个原因是semver。如果您有同一依赖项的多个不同的主要版本,NPM不能仅将所有安装重复数据消除到您的根node_modules。如何解决这个问题取决于你自己。有些人使用npm别名作为他们不同的依赖项,有些人在他们的构建工具中实现插件来解析单个安装的路径,等等。

对于那些因为问题在其依赖项中而无法使用@jimmonts答案的人,您可以使用以下代码段:

这种情况发生在我们身上,因为我们正在使用的包定义了一个元素。但此软件包被多个应用程序使用。而这些应用程序,难道你不知道吗,是相互作用的。因此customElements.define('x-tag', className)被多次调用。第二次,它会崩溃应用程序。

function safeDecorator(fn) {
// eslint-disable-next-line func-names
return function(...args) {
try {
return fn.apply(this, args);
} catch (error) {
if (
error instanceof DOMException &&
error.message.includes('has already been used with this registry')
) {
return false;
}
throw error;
}
};
}
customElements.define = safeDecorator(customElements.define);

我得到了同样的错误。你可能和我没有同样的问题,但我想我会把我的解决方案放在这里,以防将来有人遇到同样的问题。

我有两个模块都导入了同一个自定义元素模块,其中一个是导入Module.js,另一个是module.js。现在,浏览器将其视为两个独立的文件,因为URL可以区分大小写,除外我的服务器将其视为由一个文件,因为它不区分大小写(express.js),或者至少它能够解析到正确文件的路径,即使大小写不正确。因此浏览器看到两个";不同的";模块都定义了相同的自定义元素,但当我搜索源代码时,只有一个文件定义了自定义元素。

我开发了一个解决方案,在定义之前用预检查覆盖定义。它对我来说很好,只需将2行广告到你的index.js 中

customElements.defineclone = Object.assign(Object.create(Object.getPrototypeOf(customElements)).define, customElements);
customElements.define = (name, element) => customElements.get(name) || customElements.defineclone(name, element);

我遇到了这个问题,发现我调用了我的boundle.js文件两次。由于我使用的是Webpack和HtmlWebpackPlugin,HtmlWebpackPlugin将对我的绑定文件的引用添加到了我已经手动引用的index.html文件中。

所有的答案都帮助我理解了这个问题,谢谢!

在我的组织中,我们开发了一个已经存在了几年的组件库,不幸的是,各种交互项目不可能总是在同一版本上。假设WebHeader团队使用了该公司<corp-input>组件的旧版本,但某些必须包含WebHeader的页面需要使用相同组件的新版本?

我们的开发人员早就在Lit组件的customElements.define调用周围实现了一个try-catch,但这意味着页面被旧版本卡住了,WebHeader团队无法在他们的积压工作中进行升级。

好吧,我们设计了一个解决方案:如果团队知道会发生冲突,而不是使用<corp-input>,那么如果他们使用<corp-input-new>,并告诉Lit组件渲染这些标签呢?这样,尽管加载了旧的组件版本,但页眉看起来还是不错的,并且页面可以从最新版本和旧版本中受益。

以下是您的操作方法:

  1. 如果您尝试只调用customElements.define('corp-input-new', CorpInput),您将得到一个Javascript异常,说明组件只能定义为呈现一个标记名。但您所需要的只是该Component类型的副本,您可以通过使用继承免费获得该副本!所以,首先说class CorpInputNew extends CorpInput { };然后customElements.define('corp-input-new', CorpInputNew);。您可能需要在Angular的app.component.ts构造函数中执行此操作。

  2. 库的组件中可能有一个方法被硬编码为执行不希望的操作。例如,我需要扩展CorpSelect,这也意味着我需要扩展CorpSelectOption和所有在this.querySelectorAll('corp-select-option')上显式查询的函数。

    i。如果该方法不是只读的,则可以在扩展类的大括号内重新实现该方法:... extends CorpInput { update(changedProps: any): { ... } }

    ii。您可能无法访问this关键字(至少,与原始Component中用于选择类属性的关键字不同),因此请尝试自己选择并将其分配给const thisInput: any = this.querySelectorAll('corp-input-new'); thisInput.someNonPrivateFunction(...);

    iii。有时存在只读方法。在Lit中,组件可能具有类似static get selectorItem(): string { return 'corp-select-option,corp-select-group'; }的东西,不能像上面那样容易地重写。相反,您需要在扩展类定义Object.defineProperties(CorpSelectNew, { selectorItem: { value: 'corp-select-option,corp-select-group', writable: true } });之后执行此操作。

  3. 最后,您可以在组件上实现版本控制系统,以便在调试时更容易地准确识别使用的版本,因为缩小的组件Javascript是一场噩梦。在您的自定义组件中,当您注册它时,请确保您有一个公共静态属性,如";版本";。这样,您就可以通过在控制台中写入以下内容来询问浏览器注册了哪个版本:customElements.get('corp-input').VERSION

相关内容

最新更新