Guard module-scope moveBefore feature-detect for DOM-less import#47
Open
codetalcott wants to merge 1 commit into
Open
Guard module-scope moveBefore feature-detect for DOM-less import#47codetalcott wants to merge 1 commit into
codetalcott wants to merge 1 commit into
Conversation
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
Importing morphlex in a DOM-less environment (bare Node / SSR) throws on import, before any morph function is called:
The cause is the module-scope feature-detect at the top of
src/morphlex.ts:Elementis dereferenced at module-evaluation time, so any environment without a DOM global (Node without a DOM shim, SSR/prerender, a bundler evaluating the module in Node) crashes onimport. This is the only module-scope DOM access in the file — every otherElement/Node/documentreference is inside a function body or atype, so guarding this one line makes the whole module importable without a DOM.Fix
typeof Element === "function", so"moveBefore" in Element.prototypeis evaluated exactly as before — behavior is identical.false, somoveBefore()falls back toinsertBefore(moot in practice, since morphing needs a real DOM to run — this only makes the import safe).This does not attempt to make morphing work headless; it only prevents the import-time crash so morphlex can be pulled into modules that are also evaluated in Node (the common SSR / bundler case).
Test
Added
test/new/ssr-import.test.ts— stubsElementtoundefined, resets the module registry, and asserts the module imports and still exposesmorph/morphInner. It fails onmain(ReferenceError: Element is not defined) and passes with this change, so it guards the regression. It also covers the newtypeof Element !== "undefined"branch, which the happy-dom test env (whereElementis always defined) otherwise wouldn't exercise.Validation
prettier --checkclean on both files; tabs/no-semicolon style matches the surrounding code.Context
Found while making a downstream library (which vendors morphlex for DOM morphing) importable in bare Node — we currently work around it with a guarded
globalThis.Elementshim ahead of the morphlex import. This one-liner removes the need for that shim for anyone importing morphlex in a mixed Node/browser codebase.