lib: enforce using primordials.globalThis instead of global

PR-URL: https://github.com/nodejs/node/pull/38230
Backport-PR-URL: https://github.com/nodejs/node/pull/39448
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Antoine du Hamel 2021-04-13 18:54:09 +02:00 committed by Richard Lau
parent ea9003a559
commit d4f96bb926
No known key found for this signature in database
GPG Key ID: C43CEC45C17AB93C
7 changed files with 46 additions and 25 deletions

View File

@ -29,6 +29,8 @@ rules:
- error - error
- name: globalThis - name: globalThis
message: "Use `const { globalThis } = primordials;` instead of the global." message: "Use `const { globalThis } = primordials;` instead of the global."
- name: global
message: "Use `const { globalThis } = primordials;` instead of `global`."
# Custom rules in tools/eslint-rules # Custom rules in tools/eslint-rules
node-core/lowercase-name-for-primitive: error node-core/lowercase-name-for-primitive: error
node-core/non-ascii-character: error node-core/non-ascii-character: error

View File

@ -45,6 +45,7 @@ const {
ObjectGetPrototypeOf, ObjectGetPrototypeOf,
ObjectSetPrototypeOf, ObjectSetPrototypeOf,
SymbolToStringTag, SymbolToStringTag,
globalThis,
} = primordials; } = primordials;
const config = internalBinding('config'); const config = internalBinding('config');
const { deprecate } = require('internal/util'); const { deprecate } = require('internal/util');
@ -119,34 +120,35 @@ if (!config.noBrowserGlobals) {
// Override global console from the one provided by the VM // Override global console from the one provided by the VM
// to the one implemented by Node.js // to the one implemented by Node.js
// https://console.spec.whatwg.org/#console-namespace // https://console.spec.whatwg.org/#console-namespace
exposeNamespace(global, 'console', createGlobalConsole(global.console)); exposeNamespace(globalThis, 'console',
createGlobalConsole(globalThis.console));
const { URL, URLSearchParams } = require('internal/url'); const { URL, URLSearchParams } = require('internal/url');
// https://url.spec.whatwg.org/#url // https://url.spec.whatwg.org/#url
exposeInterface(global, 'URL', URL); exposeInterface(globalThis, 'URL', URL);
// https://url.spec.whatwg.org/#urlsearchparams // https://url.spec.whatwg.org/#urlsearchparams
exposeInterface(global, 'URLSearchParams', URLSearchParams); exposeInterface(globalThis, 'URLSearchParams', URLSearchParams);
const { const {
TextEncoder, TextDecoder TextEncoder, TextDecoder
} = require('internal/encoding'); } = require('internal/encoding');
// https://encoding.spec.whatwg.org/#textencoder // https://encoding.spec.whatwg.org/#textencoder
exposeInterface(global, 'TextEncoder', TextEncoder); exposeInterface(globalThis, 'TextEncoder', TextEncoder);
// https://encoding.spec.whatwg.org/#textdecoder // https://encoding.spec.whatwg.org/#textdecoder
exposeInterface(global, 'TextDecoder', TextDecoder); exposeInterface(globalThis, 'TextDecoder', TextDecoder);
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope // https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
const timers = require('timers'); const timers = require('timers');
defineOperation(global, 'clearInterval', timers.clearInterval); defineOperation(globalThis, 'clearInterval', timers.clearInterval);
defineOperation(global, 'clearTimeout', timers.clearTimeout); defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
defineOperation(global, 'setInterval', timers.setInterval); defineOperation(globalThis, 'setInterval', timers.setInterval);
defineOperation(global, 'setTimeout', timers.setTimeout); defineOperation(globalThis, 'setTimeout', timers.setTimeout);
defineOperation(global, 'queueMicrotask', queueMicrotask); defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
// Non-standard extensions: // Non-standard extensions:
defineOperation(global, 'clearImmediate', timers.clearImmediate); defineOperation(globalThis, 'clearImmediate', timers.clearImmediate);
defineOperation(global, 'setImmediate', timers.setImmediate); defineOperation(globalThis, 'setImmediate', timers.setImmediate);
} }
// Set the per-Environment callback that will be called // Set the per-Environment callback that will be called
@ -280,7 +282,7 @@ function setupProcessObject() {
value: 'process' value: 'process'
}); });
// Make process globally available to users by putting it on the global proxy // Make process globally available to users by putting it on the global proxy
ObjectDefineProperty(global, 'process', { ObjectDefineProperty(globalThis, 'process', {
value: process, value: process,
enumerable: false, enumerable: false,
writable: true, writable: true,
@ -289,7 +291,7 @@ function setupProcessObject() {
} }
function setupGlobalProxy() { function setupGlobalProxy() {
ObjectDefineProperty(global, SymbolToStringTag, { ObjectDefineProperty(globalThis, SymbolToStringTag, {
value: 'global', value: 'global',
writable: false, writable: false,
enumerable: false, enumerable: false,
@ -306,7 +308,7 @@ function setupBuffer() {
delete bufferBinding.setBufferPrototype; delete bufferBinding.setBufferPrototype;
delete bufferBinding.zeroFill; delete bufferBinding.zeroFill;
ObjectDefineProperty(global, 'Buffer', { ObjectDefineProperty(globalThis, 'Buffer', {
value: Buffer, value: Buffer,
enumerable: false, enumerable: false,
writable: true, writable: true,

View File

@ -7,6 +7,7 @@ const {
SafeMap, SafeMap,
SafeWeakMap, SafeWeakMap,
StringPrototypeStartsWith, StringPrototypeStartsWith,
globalThis,
} = primordials; } = primordials;
const { const {
@ -290,7 +291,7 @@ function initializeDeprecations() {
// deprecation path for these in ES Modules. // deprecation path for these in ES Modules.
// See https://github.com/nodejs/node/pull/26334. // See https://github.com/nodejs/node/pull/26334.
let _process = process; let _process = process;
ObjectDefineProperty(global, 'process', { ObjectDefineProperty(globalThis, 'process', {
get() { get() {
return _process; return _process;
}, },
@ -302,7 +303,7 @@ function initializeDeprecations() {
}); });
let _Buffer = Buffer; let _Buffer = Buffer;
ObjectDefineProperty(global, 'Buffer', { ObjectDefineProperty(globalThis, 'Buffer', {
get() { get() {
return _Buffer; return _Buffer;
}, },
@ -321,7 +322,7 @@ function initializeAbortController() {
AbortController, AbortController,
AbortSignal AbortSignal
} = require('internal/abort_controller'); } = require('internal/abort_controller');
ObjectDefineProperties(global, { ObjectDefineProperties(globalThis, {
AbortController: { AbortController: {
writable: true, writable: true,
enumerable: false, enumerable: false,

View File

@ -3,6 +3,10 @@
// User passed `-e` or `--eval` arguments to Node without `-i` or // User passed `-e` or `--eval` arguments to Node without `-i` or
// `--interactive`. // `--interactive`.
const {
globalThis,
} = primordials;
const { const {
prepareMainThreadExecution prepareMainThreadExecution
} = require('internal/bootstrap/pre_execution'); } = require('internal/bootstrap/pre_execution');
@ -12,7 +16,7 @@ const { addBuiltinLibsToObject } = require('internal/modules/cjs/helpers');
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
prepareMainThreadExecution(); prepareMainThreadExecution();
addBuiltinLibsToObject(global); addBuiltinLibsToObject(globalThis);
markBootstrapComplete(); markBootstrapComplete();
const source = getOptionValue('--eval'); const source = getOptionValue('--eval');

View File

@ -195,6 +195,7 @@ primordials.SafeWeakSet = makeSafe(
'Math', 'Math',
'Reflect' 'Reflect'
].forEach((name) => { ].forEach((name) => {
// eslint-disable-next-line no-restricted-globals
copyPropsRenamed(global[name], primordials, name); copyPropsRenamed(global[name], primordials, name);
}); });
@ -235,6 +236,7 @@ primordials.SafeWeakSet = makeSafe(
'WeakMap', 'WeakMap',
'WeakSet', 'WeakSet',
].forEach((name) => { ].forEach((name) => {
// eslint-disable-next-line no-restricted-globals
const original = global[name]; const original = global[name];
primordials[name] = original; primordials[name] = original;
copyPropsRenamed(original, primordials, name); copyPropsRenamed(original, primordials, name);
@ -247,6 +249,7 @@ primordials.SafeWeakSet = makeSafe(
[ [
'Promise', 'Promise',
].forEach((name) => { ].forEach((name) => {
// eslint-disable-next-line no-restricted-globals
const original = global[name]; const original = global[name];
primordials[name] = original; primordials[name] = original;
copyPropsRenamedBound(original, primordials, name); copyPropsRenamedBound(original, primordials, name);

View File

@ -3,6 +3,7 @@
const { const {
Array, Array,
ArrayIsArray, ArrayIsArray,
ArrayPrototypeFilter,
BigIntPrototypeValueOf, BigIntPrototypeValueOf,
BooleanPrototypeValueOf, BooleanPrototypeValueOf,
DatePrototypeGetTime, DatePrototypeGetTime,
@ -41,7 +42,9 @@ const {
ObjectSetPrototypeOf, ObjectSetPrototypeOf,
ReflectApply, ReflectApply,
RegExp, RegExp,
RegExpPrototypeExec,
RegExpPrototypeToString, RegExpPrototypeToString,
SafeSet,
SafeStringIterator, SafeStringIterator,
Set, Set,
SetPrototypeGetSize, SetPrototypeGetSize,
@ -55,6 +58,7 @@ const {
TypedArrayPrototypeGetLength, TypedArrayPrototypeGetLength,
TypedArrayPrototypeGetSymbolToStringTag, TypedArrayPrototypeGetSymbolToStringTag,
Uint8Array, Uint8Array,
globalThis,
uncurryThis, uncurryThis,
} = primordials; } = primordials;
@ -120,8 +124,11 @@ const { NativeModule } = require('internal/bootstrap/loaders');
let hexSlice; let hexSlice;
const builtInObjects = new Set( const builtInObjects = new SafeSet(
ObjectGetOwnPropertyNames(global).filter((e) => /^[A-Z][a-zA-Z0-9]+$/.test(e)) ArrayPrototypeFilter(
ObjectGetOwnPropertyNames(globalThis),
(e) => RegExpPrototypeExec(/^[A-Z][a-zA-Z0-9]+$/, e) !== null
)
); );
// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot

View File

@ -43,6 +43,7 @@
'use strict'; 'use strict';
const { const {
ArrayPrototypeForEach,
Error, Error,
MathMax, MathMax,
NumberIsNaN, NumberIsNaN,
@ -67,6 +68,7 @@ const {
SyntaxError, SyntaxError,
SyntaxErrorPrototype, SyntaxErrorPrototype,
WeakSet, WeakSet,
globalThis,
} = primordials; } = primordials;
const { const {
@ -984,7 +986,7 @@ REPLServer.prototype.close = function close() {
REPLServer.prototype.createContext = function() { REPLServer.prototype.createContext = function() {
let context; let context;
if (this.useGlobal) { if (this.useGlobal) {
context = global; context = globalThis;
} else { } else {
sendInspectorCommand((session) => { sendInspectorCommand((session) => {
session.post('Runtime.enable'); session.post('Runtime.enable');
@ -996,13 +998,13 @@ REPLServer.prototype.createContext = function() {
}, () => { }, () => {
context = vm.createContext(); context = vm.createContext();
}); });
for (const name of ObjectGetOwnPropertyNames(global)) { ArrayPrototypeForEach(ObjectGetOwnPropertyNames(globalThis), (name) => {
// Only set properties that do not already exist as a global builtin. // Only set properties that do not already exist as a global builtin.
if (!globalBuiltins.has(name)) { if (!globalBuiltins.has(name)) {
ObjectDefineProperty(context, name, ObjectDefineProperty(context, name,
ObjectGetOwnPropertyDescriptor(global, name)); ObjectGetOwnPropertyDescriptor(globalThis, name));
} }
} });
context.global = context; context.global = context;
const _console = new Console(this.output); const _console = new Console(this.output);
ObjectDefineProperty(context, 'console', { ObjectDefineProperty(context, 'console', {