Today we look at a new
realm, a rather abstract word, actually represents a
For example, the following code.
iframe has a separate runtime environment, the global object of
document is different from the global object of
iframe, and similarly, the
Array on the global object must be different as well.
ShadowRealm API is a new
realm with independent global objects and built-in objects.
ShadowRealm has the following type signature.
ShadowRealm instance has its own separate runtime environment, which provides two ways for us to execute the code in the runtime environment.
.evaluate(): synchronizes the execution of the code string, similar to
.importValue(): returns a
Promiseobject that executes the code string asynchronously.
Type signature of
.evaluate() works much like
eval(), the code is executed in a separate runtime environment from
.evaluate() returns a function, this function is wrapped for ease of calling externally and then run in
Whenever a value is passed into
ShadowRealm, it must be of primitive type or callable. Otherwise, an exception will be thrown.
Type signature of
You can directly import an external module that executes asynchronously and returns a
Promise, as follows.
.evaluate(), the values passed into
ShadowRealms (both the arguments and the result of the cross-environment function call) must be raw or callable.
What can ShadowRealms be used for?
- Run third-party code such as plug-ins in programs such as
- Create a programming environment in
ShadowRealmsto run user code.
- The server can run third-party code in
- Tests can be run in ShadowRealms so that the external JS execution environment is not affected and each suite can be launched in the new environment (this helps with reusability).
- Web crawling (extracting data from web pages) and web application testing, etc. can be run in
Comparison with other solutions
eval() and Function
ShadowRealms is much like
Function, but a little better than both of them: we can create new JS runtime environments and execute code in them, which protects the external JS runtime environment from the operations executed by the code.
Web Worker is a more powerful isolation mechanism than
ShadowRealms. The code in it runs in a separate process and communication is asynchronous.
However, when we want to do some more lightweight operations,
ShadowRealms is a good choice. Its algorithm allows simultaneous computation, is more convenient, and the global data management is more free.
As we mentioned before, each
iframe has its own runtime environment in which we can execute code synchronously.
ShadowRealms, it still has the following disadvantages.
- Can only use
iframein the browser.
- The need to add an
DOMto initialize it.
iframeenvironment contains the full DOM, which limits the flexibility of customization in some scenarios.
- By default, objects are cross-environmental, which means extra work is needed to ensure code security.
The vm module on Node.js
vm module for
Node.js is similar to the
ShadowRealm API, but has more features: caching the
import(), and so on. But its only drawback is that it is not cross-platform and can only be used in the
Usage Example: Running Tests in ShadowRealms
Here we see a small
Demo for running tests in
ShadowRealms. The test library collects the tests specified by
test() and allows us to run them via
Use the library to specify the test.
In the next example, we dynamically load the
my-test.js module to collect and then run tests.
Alas, there is currently no way to load the module without importing anything.
That’s why there is a default export in the last line of the previous example. We use the
ShadowRealm.importvalue() method to import the
Running Web Applications in ShadowRealms
jsdom library creates a wrapped browser environment that can be used to test
Web applications, extract data from
HTML, and more. It currently uses the
Node.js vm module, and may be updated to use
ShadowRealms in the future (the latter has the benefit of being cross-platform, while
vm currently only supports