A utility that prevents duplicate custom element registration errors by monkey-patching window.customElements.define
npx @tessl/cli install tessl/npm-lrnwebcomponents--deduping-fix@8.0.00
# Deduping Fix
1
2
Deduping Fix is a utility package that solves a critical web components platform issue where attempting to define the same custom element twice causes a hard failure. The package provides a non-breaking solution by monkey-patching the global `window.customElements.define` function to check for existing element definitions before attempting registration.
3
4
## Package Information
5
6
- **Package Name**: @lrnwebcomponents/deduping-fix
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install @lrnwebcomponents/deduping-fix`
10
11
## Core Imports
12
13
```javascript
14
import '@lrnwebcomponents/deduping-fix';
15
```
16
17
For CommonJS environments:
18
19
```javascript
20
require('@lrnwebcomponents/deduping-fix');
21
```
22
23
## Basic Usage
24
25
The package works entirely through side effects when imported. No explicit API calls are needed:
26
27
```javascript
28
import '@lrnwebcomponents/deduping-fix';
29
30
// Now safe to define custom elements multiple times
31
customElements.define('my-element', class extends HTMLElement {
32
// Element implementation
33
});
34
35
// This won't throw an error, just logs a warning
36
customElements.define('my-element', class extends HTMLElement {
37
// Different implementation - will be ignored with warning
38
});
39
```
40
41
## Architecture
42
43
Deduping Fix works by intercepting the native Custom Elements API:
44
45
- **Global Modification**: Replaces `window.customElements.define` with a wrapper function
46
- **Duplicate Detection**: Uses `customElements.get()` to check for existing definitions
47
- **Graceful Degradation**: Issues console warnings instead of throwing exceptions
48
- **Transparent Operation**: Maintains the original API contract for new element definitions
49
50
## Capabilities
51
52
### Custom Element Definition Protection
53
54
Prevents duplicate custom element registration errors by intercepting and modifying the global `customElements.define` function.
55
56
```javascript { .api }
57
/**
58
* Modified window.customElements.define function that prevents duplicate registrations
59
* @param name - The name of the custom element to define
60
* @param cl - The custom element constructor class
61
* @param conf - Optional configuration object for the custom element
62
*/
63
window.customElements.define(
64
name: string,
65
cl: CustomElementConstructor,
66
conf?: ElementDefinitionOptions
67
): void;
68
```
69
70
**Behavior Changes:**
71
72
- **Before import**: Duplicate element definitions throw `DOMException: "Failed to execute 'define' on 'CustomElementRegistry'"`
73
- **After import**: Duplicate element definitions log `console.warn("${name} has been defined twice")` and continue execution
74
75
**Usage Examples:**
76
77
```javascript
78
import '@lrnwebcomponents/deduping-fix';
79
80
// First definition - works normally
81
customElements.define('my-button', class MyButton extends HTMLElement {
82
constructor() {
83
super();
84
this.innerHTML = '<button>Click me</button>';
85
}
86
});
87
88
// Second definition - logs warning instead of throwing error
89
customElements.define('my-button', class AnotherButton extends HTMLElement {
90
constructor() {
91
super();
92
this.innerHTML = '<button>Different button</button>';
93
}
94
});
95
// Console output: "my-button has been defined twice"
96
```
97
98
**Common Use Cases:**
99
100
```javascript
101
// Development hot-reloading scenarios
102
import '@lrnwebcomponents/deduping-fix';
103
import './my-component.js'; // May be reloaded multiple times
104
105
// Dynamic imports with timing issues
106
import '@lrnwebcomponents/deduping-fix';
107
Promise.all([
108
import('./component-a.js'),
109
import('./component-b.js'), // Both might define same element
110
]).then(() => {
111
// No registration conflicts
112
});
113
114
// Legacy platform integration
115
import '@lrnwebcomponents/deduping-fix';
116
// Import multiple libraries that might define conflicting elements
117
import 'legacy-component-library-1';
118
import 'legacy-component-library-2';
119
```
120
121
## Error Handling
122
123
The package handles duplicate custom element definitions gracefully:
124
125
- **No exceptions thrown**: Prevents application crashes from duplicate definitions
126
- **Console warnings**: Provides visibility into duplicate registration attempts
127
- **Original behavior preserved**: New element definitions work exactly as before
128
- **Platform compatibility**: Works with all browsers supporting Custom Elements v1
129
130
## Browser Compatibility
131
132
- **Modern Browsers**: Chrome 54+, Firefox 63+, Safari 10.1+, Edge 79+
133
- **Requirements**: Native Custom Elements v1 support
134
- **Node.js**: Not applicable (requires browser `window` object)
135
- **Module System**: ES Modules only
136
137
## Types
138
139
```javascript { .api }
140
/**
141
* Original customElements.define function reference stored before modification
142
*/
143
declare const _customElementsDefine: (
144
name: string,
145
constructor: CustomElementConstructor,
146
options?: ElementDefinitionOptions
147
) => void;
148
149
/**
150
* Standard Custom Elements API types
151
*/
152
interface CustomElementConstructor {
153
new (): HTMLElement;
154
}
155
156
interface ElementDefinitionOptions {
157
extends?: string;
158
}
159
```