The documentation for --frozen-intrinsics says:
Only the root context is supported. There is no guarantee that globalThis.Array is indeed the default intrinsic reference. Code may break under this flag
I couldn't understand this. Can someone help me understand this in simple words with an example?
Background: I was checking nicolo-ribaudo/jest-light-runner where there is a mention of --frozen-intrinsics.
When you use --frozen-intrinsics, all the built-in JavaScript objects and functions are recursively frozen, except for globalThis.
If you run node --frozen-intrinsics, you can check it:
> Object.isFrozen(Array)
true
> Object.isFrozen(Array.prototype)
true
> Object.isFrozen(globalThis);
false
> Array.isArray = () => true; Array.isArray(2); // you cannot modify built-in properties, this will not return true
false
> globalThis.foo = 3; foo; // you can still define new globals
3
> globalThis.Array = 4; Array; // However, you can also replace existing globals
4
This prevents your code from accidentally modifying globals, so I recommended it in jest-light-runner to prevent tests from accidentally influencing each other (since it doesn't isolate test files like Jest's default runner does).
Note that you still have a communication channel by attaching new properties to the global object, so it's not an isolation mechanism.
Now, lets take a look at the docs you quoted.
Only the root context is supported.
In Node.js, you can create multiple "global contexts" using the vm built-in module. --frozen-intrinsics does not affect those contexts, so if you run node with --frozen-intrinsics:
> Object.isFrozen(Array)
true
> Object.isFrozen(require("vm").runInNewContext("Array"))
false
There is no guarantee that globalThis.Array is indeed the default intrinsic reference.
As mentioned earlier, globalThis.Array could still be replaced. However, if you have a "safe reference" to an object (either using syntax, or by storing the original Array global in a local variable), you can be sure that it's not modified:
let OriginalArray = Array;
require("untrusted-module");
globalThis.Array; // this might have been replaces
[].push; // this is still the original one
OriginalArray.isArray; // this is still the original one
Code may break under this flag
If code needs to modify built-ins, it would obviously stop working. For example, you cannot use polyfills that modify the global objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With