Skip to content

Commit

Permalink
feat: deprecate window global (#22057)
Browse files Browse the repository at this point in the history
This commit deprecates `window` global and adds deprecation
notice on each use of `window`.

We decided to proceed with removal of `window` global variable in Deno
2.0. There's a lot of code
in the wild that uses pattern like this:
```
if (typeof window !== "undefined) {
  ...
}
```
to check if the code is being run in browser. However, this check passes
fine in Deno and
most often libraries that do this check try to access some browser API
that is not available
in Deno, or use DOM APIs (which are also not available in Deno).

This situation has occurred multiple times already
and it's unfeasible to expect the whole ecosystem to migrate to new
check (and even if that
happened there's a ton of code that's already shipped and won't change).

The migration is straightfoward - replace all usages of `window` with
`globalThis` or `self`.
When Deno encounters use of `window` global it will now issue a warning,
steering users
towards required changes:

```
Warning
├ Use of deprecated "window" API.
│
├ This API will be removed in Deno 2.0. Make sure to upgrade to a stable API before then.
│
├ Suggestion: Use `globalThis` or `self` instead.
│
├ Suggestion: You can provide `window` in the current scope with: `const window = globalThis`.
│
└ Stack trace:
  └─ at file:///Users/ib/dev/deno/foo.js:7:1
```

Ref #13367.
  • Loading branch information
bartlomieju authored Jan 24, 2024
1 parent b66f5ed commit 930ce20
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 13 deletions.
1 change: 1 addition & 0 deletions cli/tests/testdata/npm/compare_globals/main.out
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ false
true
true
true
[WILDCARD]
true
false
false
Expand Down
2 changes: 1 addition & 1 deletion cli/tests/testdata/run/webstorage/logger.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
console.log(window.localStorage);
console.log(globalThis.localStorage);
6 changes: 3 additions & 3 deletions cli/tests/testdata/run/webstorage/serialization.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
window.sessionStorage.setItem("hello", "deno");
globalThis.sessionStorage.setItem("hello", "deno");

console.log(window.localStorage);
console.log(window.sessionStorage);
console.log(globalThis.localStorage);
console.log(globalThis.sessionStorage);
2 changes: 1 addition & 1 deletion cli/tests/testdata/run/webstorage/setter.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
window.localStorage.setItem("hello", "deno");
globalThis.localStorage.setItem("hello", "deno");
12 changes: 10 additions & 2 deletions runtime/js/98_global_scope_window.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

import { core, primordials } from "ext:core/mod.js";
import { core, internals, primordials } from "ext:core/mod.js";
const {
op_bootstrap_language,
op_bootstrap_numcpus,
Expand Down Expand Up @@ -108,7 +108,15 @@ const mainRuntimeGlobalProperties = {
Location: location.locationConstructorDescriptor,
location: location.locationDescriptor,
Window: globalInterfaces.windowConstructorDescriptor,
window: util.getterOnly(() => globalThis),
window: util.getterOnly(() => {
internals.warnOnDeprecatedApi(
"window",
new Error().stack,
"Use `globalThis` or `self` instead.",
"You can provide `window` in the current scope with: `const window = globalThis`.",
);
return globalThis;
}),
self: util.getterOnly(() => globalThis),
Navigator: util.nonEnumerable(Navigator),
navigator: util.getterOnly(() => navigator),
Expand Down
15 changes: 9 additions & 6 deletions runtime/js/99_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ let globalThis_;
let deprecatedApiWarningDisabled = false;
const ALREADY_WARNED_DEPRECATED = new SafeSet();

function warnOnDeprecatedApi(apiName, stack, suggestion) {
function warnOnDeprecatedApi(apiName, stack, ...suggestions) {
if (deprecatedApiWarningDisabled) {
return;
}
Expand Down Expand Up @@ -155,11 +155,14 @@ function warnOnDeprecatedApi(apiName, stack, suggestion) {
"%c\u251c This API will be removed in Deno 2.0. Make sure to upgrade to a stable API before then.",
"color: yellow;",
);
console.error("%c\u2502", "color: yellow;");
console.error(
`%c\u251c Suggestion: ${suggestion}`,
"color: yellow;",
);
for (let i = 0; i < suggestions.length; i++) {
const suggestion = suggestions[i];
console.error("%c\u2502", "color: yellow;");
console.error(
`%c\u251c Suggestion: ${suggestion}`,
"color: yellow;",
);
}
if (isFromRemoteDependency) {
console.error("%c\u2502", "color: yellow;");
console.error(
Expand Down

0 comments on commit 930ce20

Please sign in to comment.