Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[npm]: window global cannot be set #19286

Closed
marvinhagemeister opened this issue May 26, 2023 · 6 comments
Closed

[npm]: window global cannot be set #19286

marvinhagemeister opened this issue May 26, 2023 · 6 comments

Comments

@marvinhagemeister
Copy link
Contributor

marvinhagemeister commented May 26, 2023

A couple of testing frameworks rely on JSDOM, happy-dom and similar libraries to provide a fake DOM and browser event implementation. This usually relies on the window global being created (or patched).

In Deno the global variable window seems to be special cased. I'm not able to modify window and read the changes inside an npm package. This is a very common scenarios with the mentioned libraries. Typically they set up window as a global, and another import to the framework reads that global.

// Pseudo example
import "./set-up-happy-dom"; // <-- imaginary file, sets up global `document` and `window`
import React from "react";
import ReactDOM from "react-dom/client"; // <-- reads properties of `window`

In ESM mode the window global exists which seems to be Deno's Window object. With a CommonJS package the window global is not present which leads to a TypeError.

Steps to reproduce

  1. Clone https://github.com/marvinhagemeister/deno-npm-window
  2. Run deno run -A foo.js

If successful, the string "it works" should have been printed to the console.

@marvinhagemeister
Copy link
Contributor Author

Looking a bit into this:

  • Deno has its own Window object. It hat a few familiar APIs from a browser's Window object
  • The window global is removed as part of the require module code here:
    "(function (exports, require, module, __filename, __dirname, globalThis) { const { Buffer, clearImmediate, clearInterval, clearTimeout, console, global, process, setImmediate, setInterval, setTimeout, performance} = globalThis; var window = undefined; (function () {",

Not sure how to best solve this. Removing the window global is kinda correct for the common case as that's not available in node. But that poses the question how you can polyfill it for testing. For the test files itself it's possible to load some sort of setup module at the start, but that doesn't work for transient npm dependencies. Libraries like react-dom happily read window.event which then leads to a TypeError.

@dsherret
Copy link
Member

We need to remove the window global from Deno IMO (#13367) then not special case it for the node code.

@marvinhagemeister
Copy link
Contributor Author

+1 on removing it. I understand the original reasoning behind it, but having something called window is confusing imo. There is lots of existing code out there that relies on typeof window === "undefined" to check if the code is running on the server or in a browser. We break that assumption currently.

See https://github.com/search?q=%22typeof+window+%3D%3D%3D+%5C%22undefined%5C%22%22&type=code

@valpackett
Copy link

The deletion for the npm commonjs context doesn't even seem to be working 🤔

Running deno run npm:[email protected] with deno 1.45.3, the following detection code:

https://github.com/TiddlyWiki/TiddlyWiki5/blob/9069992163f114a4eec2162c059e5848f2a7b6d9/boot/bootprefix.js#L23-L28

detects both window and process globals. I can even add console.log calls to the cached npm file and see:

Window {}
EventEmitter [process] {
…
  versions: {
    node: "20.11.1",

valpackett added a commit to valpackett/TiddlyWiki5 that referenced this issue Jul 26, 2024
Deno's node emulation can run TiddlyWiki now that it supports the VM isolates API, but the window global exists in that environment, so both browser and node were being detected, causing the autoboot to trip up on nonexistent argv, as the boot was happening in the constructor right before argv was set.

Ref: denoland/deno#19286
Ref: https://github.com/flexdinesh/browser-or-node
Jermolene pushed a commit to TiddlyWiki/TiddlyWiki5 that referenced this issue Jul 26, 2024
Deno's node emulation can run TiddlyWiki now that it supports the VM isolates API, but the window global exists in that environment, so both browser and node were being detected, causing the autoboot to trip up on nonexistent argv, as the boot was happening in the constructor right before argv was set.

Ref: denoland/deno#19286
Ref: https://github.com/flexdinesh/browser-or-node
@petamoriken
Copy link
Contributor

@valpackett Please try DENO_FUTURE=1 deno run (#22318)

tsukasa-au pushed a commit to tsukasa-au/TiddlyWiki5 that referenced this issue Aug 3, 2024
…dlyWiki#8423)

Deno's node emulation can run TiddlyWiki now that it supports the VM isolates API, but the window global exists in that environment, so both browser and node were being detected, causing the autoboot to trip up on nonexistent argv, as the boot was happening in the constructor right before argv was set.

Ref: denoland/deno#19286
Ref: https://github.com/flexdinesh/browser-or-node
@bartlomieju
Copy link
Member

This appears to no longer be an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants