Description
The Problem
I'd like to be able to inject the document
to use for my render()
to allow me to use happy-dom or JSDOM to test my Preact components without assigning a global document.
Currently you must assign it to the globalThis
object like so:
import { h, render } from 'preact'
// Imagine this is a mock Window
const browser = new Browser(`<body></body>`)
// Assign itto the global context so Preact can use them
globalThis.document = browser.document
// Run the preact render
render(<div>Hi</div>, browser.document.body)
However this prevents me from being able to run the tests concurrently
setTimeout(() => {
const browser = new Browser(`<body></body>`)
globalThis.document = browser.document
render(<div>Hi</div>, browser.document.body)
})
setTimeout(() => {
const browser = new Browser(`<body></body>`)
globalThis.document = browser.document
render(<div>Hi</div>, browser.document.body)
})
What I've Tried
I have tried to use Node's node:vm
module to alter the globalThis context, however this does not work as it doesn't have access to imports.
I have tried bundling the import and using that as a script evaluation in the mock browser, however this is slow and cumbersome, negating the benefits of making tests concurrent.
Request
From what I can tell, the globalThis.document
is used in the diff
function: https://github.com/preactjs/preact/blob/main/src/diff/index.js#L414
- Use
element.ownerDocument
This would allow preact to use the document
object associated with the current HTMLElement
- Add a new function, something like
renderToDom(component, target, globalContext)
.
This would allow me to inject the specific DOM into the render pipeline. This might cause issues with iframes though
const browser = new Browser(`<body></body>`)
renderToDom(
<div>Hi</div>,
browser.document.body,
browser.document, // <- here
)
I can raise a PR for this, is that okay?