diff --git a/cli/schemas/config-file.v1.json b/cli/schemas/config-file.v1.json index ed80eb17b1..9f4737fa0a 100644 --- a/cli/schemas/config-file.v1.json +++ b/cli/schemas/config-file.v1.json @@ -534,6 +534,7 @@ "http", "kv", "net", + "node-globals", "sloppy-imports", "temporal", "unsafe-proto", diff --git a/runtime/fmt_errors.rs b/runtime/fmt_errors.rs index 28cd702966..6c05fbc633 100644 --- a/runtime/fmt_errors.rs +++ b/runtime/fmt_errors.rs @@ -339,28 +339,40 @@ fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec { FixSuggestion::info(cstr!( "Buffer is not available in the global scope in Deno." )), - FixSuggestion::hint(cstr!("Import it explicitly with import { Buffer } from \"node:buffer\";.")), + FixSuggestion::hint_multiline(&[ + cstr!("Import it explicitly with import { Buffer } from \"node:buffer\";,"), + cstr!("or run again with --unstable-node-globals flag to add this global."), + ]), ]; } else if msg.contains("clearImmediate is not defined") { return vec![ FixSuggestion::info(cstr!( "clearImmediate is not available in the global scope in Deno." )), - FixSuggestion::hint(cstr!("Import it explicitly with import { clearImmediate } from \"node:timers\";.")), + FixSuggestion::hint_multiline(&[ + cstr!("Import it explicitly with import { clearImmediate } from \"node:timers\";,"), + cstr!("or run again with --unstable-node-globals flag to add this global."), + ]), ]; } else if msg.contains("setImmediate is not defined") { return vec![ FixSuggestion::info(cstr!( "setImmediate is not available in the global scope in Deno." )), - FixSuggestion::hint(cstr!("Import it explicitly with import { setImmediate } from \"node:timers\";.")), + FixSuggestion::hint_multiline( + &[cstr!("Import it explicitly with import { setImmediate } from \"node:timers\";,"), + cstr!("or run again with --unstable-node-globals flag to add this global."), + ]), ]; } else if msg.contains("global is not defined") { return vec![ FixSuggestion::info(cstr!( "global is not available in the global scope in Deno." )), - FixSuggestion::hint(cstr!("Use globalThis instead, or assign globalThis.global = globalThis.")), + FixSuggestion::hint_multiline(&[ + cstr!("Use globalThis instead, or assign globalThis.global = globalThis,"), + cstr!("or run again with --unstable-node-globals flag to add this global."), + ]), ]; } else if msg.contains("openKv is not a function") { return vec![ diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index 11f618ce27..079338510b 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -144,12 +144,13 @@ const unstableIds = { http: 5, kv: 6, net: 7, - otel: 8, - process: 9, - temporal: 10, - unsafeProto: 11, - webgpu: 12, - workerOptions: 13, + nodeGlobals: 8, + otel: 9, + process: 10, + temporal: 11, + unsafeProto: 12, + webgpu: 13, + workerOptions: 14, }; const denoNsUnstableById = { __proto__: null }; diff --git a/runtime/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index 7a27238996..f8e76b7ce7 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -32,6 +32,8 @@ import { DOMException } from "ext:deno_web/01_dom_exception.js"; import * as abortSignal from "ext:deno_web/03_abort_signal.js"; import * as imageData from "ext:deno_web/16_image_data.js"; import process from "node:process"; +import Buffer from "node:buffer"; +import { clearImmediate, setImmediate } from "node:timers"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; import * as webgpuSurface from "ext:deno_webgpu/02_surface.js"; import { unstableIds } from "ext:runtime/90_deno_ns.js"; @@ -300,4 +302,15 @@ unstableForWindowOrWorkerGlobalScope[unstableIds.net] = { unstableForWindowOrWorkerGlobalScope[unstableIds.webgpu] = {}; +unstableForWindowOrWorkerGlobalScope[unstableIds.nodeGlobals] = { + Buffer: core.propWritable(Buffer), + setImmediate: core.propWritable(setImmediate), + clearImmediate: core.propWritable(clearImmediate), + global: { + enumerable: true, + configurable: true, + get: () => globalThis, + }, +}; + export { unstableForWindowOrWorkerGlobalScope, windowOrWorkerGlobalScope }; diff --git a/runtime/lib.rs b/runtime/lib.rs index 6fb8c5f3da..8a228c5b59 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -99,24 +99,30 @@ pub static UNSTABLE_GRANULAR_FLAGS: &[UnstableGranularFlag] = &[ show_in_help: true, id: 7, }, + UnstableGranularFlag { + name: "node-globals", + help_text: "Expose Node globals everywhere", + show_in_help: true, + id: 8, + }, UnstableGranularFlag { name: "otel", help_text: "Enable unstable OpenTelemetry features", show_in_help: false, - id: 8, + id: 9, }, // TODO(bartlomieju): consider removing it UnstableGranularFlag { name: ops::process::UNSTABLE_FEATURE_NAME, help_text: "Enable unstable process APIs", show_in_help: false, - id: 9, + id: 10, }, UnstableGranularFlag { name: "temporal", help_text: "Enable unstable Temporal API", show_in_help: true, - id: 10, + id: 11, }, UnstableGranularFlag { name: "unsafe-proto", @@ -124,19 +130,19 @@ pub static UNSTABLE_GRANULAR_FLAGS: &[UnstableGranularFlag] = &[ show_in_help: true, // This number is used directly in the JS code. Search // for "unstableIds" to see where it's used. - id: 11, + id: 12, }, UnstableGranularFlag { name: deno_webgpu::UNSTABLE_FEATURE_NAME, help_text: "Enable unstable `WebGPU` APIs", show_in_help: true, - id: 12, + id: 13, }, UnstableGranularFlag { name: ops::worker_host::UNSTABLE_FEATURE_NAME, help_text: "Enable unstable Web Worker APIs", show_in_help: true, - id: 13, + id: 14, }, ]; diff --git a/tests/specs/lint/node_globals_no_duplicate_imports/main.out b/tests/specs/lint/node_globals_no_duplicate_imports/main.out index 058b80795d..ce5523f99c 100644 --- a/tests/specs/lint/node_globals_no_duplicate_imports/main.out +++ b/tests/specs/lint/node_globals_no_duplicate_imports/main.out @@ -4,4 +4,5 @@ const _foo = setImmediate; at [WILDCARD]main.ts:3:14 info: setImmediate is not available in the global scope in Deno. - hint: Import it explicitly with import { setImmediate } from "node:timers";. + hint: Import it explicitly with import { setImmediate } from "node:timers";, + or run again with --unstable-node-globals flag to add this global. diff --git a/tests/specs/run/node_globals_hints/buffer.out b/tests/specs/run/node_globals_hints/buffer.out index 4980e6d129..858f404ab5 100644 --- a/tests/specs/run/node_globals_hints/buffer.out +++ b/tests/specs/run/node_globals_hints/buffer.out @@ -4,4 +4,5 @@ Buffer; at [WILDCARD]buffer.js:1:1 info: Buffer is not available in the global scope in Deno. - hint: Import it explicitly with import { Buffer } from "node:buffer";. + hint: Import it explicitly with import { Buffer } from "node:buffer";, + or run again with --unstable-node-globals flag to add this global. diff --git a/tests/specs/run/node_globals_hints/clear_immediate.out b/tests/specs/run/node_globals_hints/clear_immediate.out index ecd34babef..a973a31723 100644 --- a/tests/specs/run/node_globals_hints/clear_immediate.out +++ b/tests/specs/run/node_globals_hints/clear_immediate.out @@ -4,4 +4,5 @@ clearImmediate; at [WILDCARD]clear_immediate.js:1:1 info: clearImmediate is not available in the global scope in Deno. - hint: Import it explicitly with import { clearImmediate } from "node:timers";. + hint: Import it explicitly with import { clearImmediate } from "node:timers";, + or run again with --unstable-node-globals flag to add this global. diff --git a/tests/specs/run/node_globals_hints/global.out b/tests/specs/run/node_globals_hints/global.out index e090d32e29..ad01ac426d 100644 --- a/tests/specs/run/node_globals_hints/global.out +++ b/tests/specs/run/node_globals_hints/global.out @@ -4,4 +4,5 @@ global; at [WILDCARD]global.js:1:1 info: global is not available in the global scope in Deno. - hint: Use globalThis instead, or assign globalThis.global = globalThis. + hint: Use globalThis instead, or assign globalThis.global = globalThis, + or run again with --unstable-node-globals flag to add this global. diff --git a/tests/specs/run/node_globals_hints/set_immediate.out b/tests/specs/run/node_globals_hints/set_immediate.out index 38859ff5d7..b3feb3127d 100644 --- a/tests/specs/run/node_globals_hints/set_immediate.out +++ b/tests/specs/run/node_globals_hints/set_immediate.out @@ -4,4 +4,5 @@ setImmediate; at [WILDCARD]set_immediate.js:1:1 info: setImmediate is not available in the global scope in Deno. - hint: Import it explicitly with import { setImmediate } from "node:timers";. + hint: Import it explicitly with import { setImmediate } from "node:timers";, + or run again with --unstable-node-globals flag to add this global. diff --git a/tests/specs/run/unstable/__test__.jsonc b/tests/specs/run/unstable/__test__.jsonc index 3ddcdb583c..bceb2ac12b 100644 --- a/tests/specs/run/unstable/__test__.jsonc +++ b/tests/specs/run/unstable/__test__.jsonc @@ -20,6 +20,11 @@ "exitCode": 1, "output": "kv.out" }, + "node_globals": { + "args": "run --unstable-node-globals node_globals.ts", + "exitCode": 0, + "output": "node_globals.out" + }, "temporal": { "args": "run temporal.ts", "exitCode": 1, diff --git a/tests/specs/run/unstable/node_globals.out b/tests/specs/run/unstable/node_globals.out new file mode 100644 index 0000000000..77045c7cbd --- /dev/null +++ b/tests/specs/run/unstable/node_globals.out @@ -0,0 +1,4 @@ +global: true +Buffer: true +setImmediate: true +clearImmediate: true diff --git a/tests/specs/run/unstable/node_globals.ts b/tests/specs/run/unstable/node_globals.ts new file mode 100644 index 0000000000..706b7eb654 --- /dev/null +++ b/tests/specs/run/unstable/node_globals.ts @@ -0,0 +1,7 @@ +import * as nodeBuffer from "node:buffer"; +import * as nodeTimers from "node:timers"; + +console.log(`global: ${globalThis === global}`); +console.log(`Buffer: ${Buffer === nodeBuffer.default}`); +console.log(`setImmediate: ${setImmediate === nodeTimers.setImmediate}`); +console.log(`clearImmediate: ${clearImmediate === nodeTimers.clearImmediate}`);