fix: guard customElements.define against double-registration#28
Open
dmchaledev wants to merge 1 commit into
Open
fix: guard customElements.define against double-registration#28dmchaledev wants to merge 1 commit into
dmchaledev wants to merge 1 commit into
Conversation
Loading the module more than once on the same page (a CDN <script> plus a bundled copy, or two independently bundled widgets) called define() with an already-used name, throwing an uncaught DOMException that breaks the host page. Register the element only when it isn't already defined. Adds test/define-guard.test.mjs, which re-imports the module with a registry shim that throws on duplicate define (mirroring the browser) to lock in the guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S7BWmqwjZtKT4VbeAWGqh7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The element is registered unconditionally at the bottom of the module:
CustomElementRegistry.define()throws aDOMExceptionif the name is alreadyregistered. So if this module is evaluated more than once on the same page,
the second evaluation throws an uncaught error that aborts the rest of that
script and can break the host page.
This is a realistic scenario for a distributable web component:
<script type="module">and alsopulls in a bundled copy via a framework dependency.
@main/@latest, resolving totwo module instances.
The failure mode is silent in dev (one copy) and only surfaces in the field,
which makes it especially worth guarding at the source.
Fix
Register only when the name isn't already taken — the standard defensive
pattern for shippable custom elements:
Test
Adds
test/define-guard.test.mjs, which installs acustomElementsshim thatthrows on duplicate
define()(mirroring browser behavior) and then imports themodule twice (using a query-string suffix to force a second ESM evaluation). The
test fails against the old unguarded code and passes with the guard.
Verified locally:
# pass 0 / # fail 1# tests 66 / # pass 66 / # fail 0Scope
Single-file behavior change plus one test and a CHANGELOG entry. No public API,
output shape, or calculation change.
🤖 Generated with Claude Code
Generated by Claude Code