fix: make module importable in DOM-free environments (Node/SSR)#39
Open
dmchaledev wants to merge 1 commit into
Open
fix: make module importable in DOM-free environments (Node/SSR)#39dmchaledev wants to merge 1 commit into
dmchaledev wants to merge 1 commit into
Conversation
The package advertises a "pure DOM-free calculator" (`import { calculate }`)
and index.d.ts documents calculate() as "no DOM required", plus the README
claims Next.js support. But the module referenced HTMLElement (superclass),
document.createElement, and customElements.define at top level, so importing
it in Node/SSR threw `ReferenceError: document is not defined` at load time.
The existing tests only passed because they inject a full DOM shim into
globalThis before importing.
Guard the three DOM touchpoints so the module loads without a browser:
- derive the template's HTML into a plain string; only build the <template>
element when `document` exists
- extend a plain base class when `HTMLElement` is undefined so the class
declaration itself doesn't throw off-DOM
- register the custom element only when `customElements` exists
Add test/dom-free.test.mjs, which imports the module with no DOM shim
(node --test runs each file in its own process) and calls calculate(), as
a regression guard. The web-component path is unchanged in the browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CBGKeWziEpyQeGBiD1LiKv
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 package advertises a pure, DOM-free calculator and Next.js support, but the module can't actually be imported outside a browser.
README.md: "Or import the pure DOM-free calculator:import { calculate } from '@hailbytes/vulnerability-calculator';" and lists Next.js as a supported host.index.d.ts:calculate()is documented as "Pure infrastructure-sizing calculation — no DOM required."Yet three top-level statements execute DOM references at module-load time:
class HailbytesVulnCalculator extends HTMLElementHTMLElement(superclass)const TMPL = document.createElement('template')documentcustomElements.define(...)customElementsSo a plain Node / SSR / Next.js server component import throws immediately:
The existing tests don't catch this because they inject a full DOM shim into
globalThisbefore importing the module — so the real off-DOM path was never exercised.Fix
Guard the three DOM touchpoints so the module loads without a browser, leaving the in-browser web-component path byte-for-byte unchanged:
<template>element whendocumentexists.HTMLElementis undefined, so the class declaration itself doesn't throw off-DOM. (The constructor's DOM calls are only reached when the browser instantiates the element, which never happens off-DOM.)customElements.define()only whencustomElementsexists.Verification
Direct import now works with no shim:
Adds
test/dom-free.test.mjsas a regression guard — it imports the module without any DOM shim (node --testruns each test file in its own process) and callscalculate(). Full suite is green:Scope
One source file + one new test. No API, output, or browser-behavior changes; purely makes the already-documented off-DOM import contract actually hold.
🤖 Generated with Claude Code
https://claude.ai/code/session_01CBGKeWziEpyQeGBiD1LiKv
Generated by Claude Code