Skip to content

Commit 524a62b

Browse files
committed
[GR-26149] JavaScript documentation review as part of the task force.
PullRequest: js/1722
2 parents a54a771 + 199c274 commit 524a62b

12 files changed

+429
-455
lines changed

docs/user/FAQ.md

Lines changed: 36 additions & 37 deletions
Large diffs are not rendered by default.

docs/user/JavaInteroperability.md

Lines changed: 72 additions & 76 deletions
Large diffs are not rendered by default.

docs/user/JavaScriptCompatibility.md

Lines changed: 92 additions & 84 deletions
Large diffs are not rendered by default.

docs/user/Multithreading.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
# Multithreading
22

3-
GraalVM JavaScript supports multithreading.
3+
Running JavaScript on GraalVM supports multithreading.
44
Depending on the usage scenario, threads can be used to execute parallel JavaScript code using multiple [`Context`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.html) objects, or multiple [Worker](https://nodejs.org/api/worker_threads.html) threads.
55

66
## Multithreading with Java and JavaScript
77

8-
GraalVM JavaScript supports multithreading in the context of Java interoperability.
9-
The basic model of multi-threaded execution supported by GraalVM JavaScript is a "share-nothing" model that should be familiar to any JavaScript developer:
8+
Multithreading is supported when running JavaScript in the context of Java interoperability.
9+
The basic model of multi-threaded execution supported by GraalVM is a "share-nothing" model that should be familiar to any JavaScript developer:
1010

11-
1. An arbitrary number of JS `Context`s can be created, but they should be used by one thread at a time.
11+
1. An arbitrary number of JavaScript `Context`s can be created, but they should be used by one thread at a time.
1212
2. Concurrent access to JavaScript objects is not allowed: any JavaScript object cannot be accessed by more than one thread at a time.
1313
3. Concurrent access to Java objects is allowed: any Java object can be accessed by any Java or JavaScript thread, concurrently.
1414

15-
A JavaScript `Context` cannot be accessed by two or more threads, concurrently.
16-
It is however possible to access a same `Context` from multiple threads using proper syncronization, to ensure that concurrent access never happens.
15+
A JavaScript `Context` cannot be accessed by two or more threads, concurrently, but it is possible to access the same `Context` from multiple threads using proper syncronization, to ensure that concurrent access never happens.
1716

18-
#### Examples
17+
### Examples
1918

2019
The GraalVM JavaScript [unit tests](https://github.com/graalvm/graaljs/tree/master/graal-js/src/com.oracle.truffle.js.test.threading/src/com/oracle/truffle/js/test/threading) contain several examples of multi-threaded Java/JavaScript interactions.
2120
The most notable ones describe how:
@@ -28,16 +27,16 @@ The most notable ones describe how:
2827

2928
## Multithreading with Node.js
3029

31-
The basic multi-threading model of GraalVM JavaScript applies to Node.js applications as well.
32-
In Node.js, a [Worker](https://nodejs.org/api/worker_threads.html#worker_threads_worker_threads) thread can be created to execute JavaScript code in parallel, but JavaScript objects cannot be shared between workers.
33-
On the contrary, a Java object created with GraalVM Java interoperability (e.g., using `Java.type()`) _can_ be shared between Node.js workers.
30+
The basic multithreading model of GraalVM JavaScript applies to Node.js applications as well.
31+
In Node.js, a [Worker](https://nodejs.org/api/worker_threads.html#worker_threads_worker_threads) thread can be created to execute JavaScript code in parallel, but JavaScript objects cannot be shared between Workers.
32+
On the contrary, a Java object created with GraalVM Java interoperability (e.g., using `Java.type()`) can be shared between Node.js Workers.
3433
This allows multi-threaded Node.js applications to share Java objects.
3534

36-
#### Examples
35+
### Examples
3736

3837
The GraalVM Node.js [unit tests](https://github.com/graalvm/graaljs/tree/master/graal-nodejs/test/graal/unit) contain several examples of multi-threaded Node.js applications.
3938
The most notable examples show how:
4039

4140
1. [Node.js worker threads can execute Java code](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/worker.js).
4241
2. [Java objects can be shared between Node.js worker threads](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/javaMessages.js).
43-
3. [JavaScript `Promise` objects can be used to `await` on messages from workers, using Java objects to bind promises to worker messages](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/workerInteropPromises.js)
42+
3. [JavaScript `Promise` objects can be used to `await` on messages from workers, using Java objects to bind promises to worker messages](https://github.com/graalvm/graaljs/blob/master/graal-nodejs/test/graal/unit/workerInteropPromises.js).

docs/user/NashornMigrationGuide.md

Lines changed: 55 additions & 55 deletions
Large diffs are not rendered by default.

docs/user/NodeJS.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,30 @@ Applications can freely import and use NPM packages, including native ones.
55

66
## Running Node.js Applications
77

8-
To run Node.js-based applications, use the `node` binary executable in the GraalVM distribution:
9-
```
8+
To run Node.js-based applications, use the `node` launcher in the GraalVM distribution:
9+
```shell
1010
$GRAALVM_HOME/bin/node [options] [filename] [args]
1111
```
1212

13-
GraalVM's Node.js is based on a recent version of Node.js, and runs the GraalVM JavaScript engine instead of Google V8. Thus, some internal features (e.g., VM-internal statistics or configuration, profiling, debugging, etc.) are unsupported, or supported with potentially different behavior.
13+
GraalVM's Node.js runtime is based on a recent version of Node.js, and runs the
14+
GraalVM JavaScript engine instead of Google V8. Thus, some internal features (e.g.,
15+
VM-internal statistics, configuration, profiling, debugging, etc.) are
16+
unsupported, or supported with potentially different behavior.
1417

15-
The `node` executable is largely compatible with Node.js, and features additional GraalVM-specific functionalities (e.g., interoperability with Java and all other GraalVM languages).
18+
The `node` command is largely compatible with Node.js, and features additional GraalVM-specific functionalities (e.g., interoperability with Java and all other GraalVM languages).
1619
A list of available options can be obtained with `node --help`.
1720

1821
## Installing Packages Using `npm`
1922

20-
To install a Node.js package, you can use the `npm` executable in the `$GRAALVM_HOME/bin` folder of GraalVM.
21-
The `npm` executable is equivalent to the default NPM command, and supports most of its options.
23+
To install a Node.js package, you can use the `npm` launcher from the GraalVM's `/bin` folder.
24+
The `npm` command is equivalent to the default NPM command, and supports most of its options.
2225

2326
An NPM package can be installed with:
24-
```
27+
```shell
2528
$GRAALVM_HOME/bin/npm install <package>
2629
```
27-
As the `npm` executable of GraalVM is largely compatible with NPM, packages will be installed in the `node_modules` folder, as expected.
30+
31+
As the `npm` command of GraalVM is largely compatible with NPM, packages will be installed in the `node_modules` folder, as expected.
2832

2933
### Installing `npm` Packages Globally
3034

@@ -33,7 +37,7 @@ By default, `npm` installs global packages in the path where the `node` executab
3337
In GraalVM, this means that global packages will create files in the GraalVM folder.
3438
To avoid writing to the GraalVM folder, the default global installation folder of `npm` can be modified by setting the `$PREFIX` environment variable, or by specifying the `--prefix` option when running `npm install`.
3539
For example, the following command will install global packages in the `/foo/bar` folder:
36-
```
40+
```shell
3741
$GRAALVM_HOME/bin/npm install --prefix /foo/bar -g <package>
3842
```
39-
More details about `prefix` can be found in the official npm documentation.
43+
More details about `prefix` can be found in the [official NPM documentation](https://docs.npmjs.com/cli/prefix.html).

docs/user/NodeJSVSJavaScriptContext.md

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Differences Between Node.js and Java Embeddings
22

3-
GraalVM's JavaScript engine is a fully-compliant ECMA2020 language runtime.
4-
As such, it can run JavaScript code in a variety of embedding scenarios, including the Oracle [RDBMS](https://www.graalvm.org/docs/examples/mle-oracle/), any Java-based application and Node.js.
3+
GraalVM provides a fully-compliant ECMAScript 2020 JavaScript language runtime.
4+
As such, it can run JavaScript code in a variety of embedding scenarios, including the Oracle [RDBMS](https://www.graalvm.org/docs/examples/mle-oracle/), any Java-based application, and Node.js.
55

66
Depending on the GraalVM's JavaScript embedding scenario, applications have access to different built-in capabilities.
7-
For example, Node.js applications running on GraalVM's JavaScript engine have access to all of Node.js' APIs, including built-in Node.js' modules such as `'fs'`, `'http'`, etc.
8-
Conversely, JavaScript code embedded in a Java application has access to limited capabilities, as specified through the [Context API](https://www.graalvm.org/reference-manual/embed-languages/#compile-and-run-a-polyglot-application), and do _not_ have access to Node.js built-in modules.
7+
For example, Node.js applications running on GraalVM's have access to all of Node.js' APIs, including built-in Node.js modules such as `fs` and `http`, etc.
8+
9+
Conversely, JavaScript code embedded in a Java application has access to limited capabilities, as specified through the [Context API](https://www.graalvm.org/reference-manual/embed-languages/#compile-and-run-a-polyglot-application), and do not have access to Node.js built-in modules.
910

1011
This guide describes the main differences between a Node.js application and a GraalVM JavaScript application embedded in Java.
1112

@@ -27,75 +28,70 @@ In this scenario, Java classes can be exposed to the Node.js application by usin
2728
JavaScript applications can interact with Java classes using the `Java` built-in object.
2829
The object is not available by default, and can be enabled in the following way:
2930

30-
1. In Node.js, start GraalVM using the `bin/node --jvm` command
31+
1. In Node.js, start GraalVM using the `bin/node --jvm` command.
3132
2. In Java, create a GraalVM context using the `withHostInterop()` option, e.g.:
32-
```
33+
```java
3334
Context.create("js").withHostInterop()
3435
```
35-
More details on the Java interoperability capabilities of GraalVM JavaScript are available in the [Java Interoperability](https://github.com/graalvm/graaljs/blob/master/docs/user/JavaInteroperability.md) guide.
36+
More details on the Java interoperability capabilities of GraalVM JavaScript are available in [Java Interoperability](https://github.com/graalvm/graaljs/blob/master/docs/user/JavaInteroperability.md).
3637

3738
## Multithreading
3839

3940
A GraalVM context running JavaScript enforces a "share-nothing" model of parallelism: no JavaScript values can be accessed by two concurrent Java threads at the same time.
40-
In order to leverage parallel execution, multiple contexts have to be created and executed from multiple threads.
41+
In order to leverage parallel execution, multiple contexts have to be created and executed from multiple threads:
4142

4243
1. In Node.js, multiple contexts can be created using Node.js' [Worker threads](https://nodejs.org/api/worker_threads.html) API.
43-
The worker threads API ensures that no sharing can happen between two parallel contexts.
44+
The Worker threads API ensures that no sharing can happen between two parallel contexts.
4445
2. In Java, multiple contexts can be executed from multiple threads.
4546
As long as a context is not accessed by two threads at the same time, parallel execution happens safely.
4647

4748
More details on parallel execution in GraalVM JavaScript are available in [this blog post](https://medium.com/graalvm/multi-threaded-java-javascript-language-interoperability-in-graalvm-2f19c1f9c37b).
4849

49-
5050
## Java Libraries
5151

5252
Java libraries can be accessed from JavaScript in GraalVM through the `Java` built-in object.
53-
In order for a Java library to be accessible from a `Context`, its `jar` files need to be added to the GraalVM class path.
54-
This can be done in the following way:
53+
In order for a Java library to be accessible from a `Context`, its `jar` files need to be added to the GraalVM classpath. This can be done in the following way:
5554

5655
1. In Node.js, the classpath can be modified using the `--jvm.cp` option.
5756
2. In Java, the default Java's `-cp` option can be used.
5857

59-
More details on GraalVM command line options are available in the [Options](https://github.com/graalvm/graaljs/blob/master/docs/user/Options.md) guide.
58+
More details on GraalVM command line options are available in [Options](https://github.com/graalvm/graaljs/blob/master/docs/user/Options.md).
6059

6160
## JavaScript Modules
6261

6362
Many popular JavaScript modules such as those available on the `npm` package registry can be used from Node.js as well as from Java.
6463
GraalVM JavaScript is compatible with the latest ECMA standard, and supports ECMAScript modules (ECM).
6564
CommonJS (CJS) modules are supported when running with Node.js.
66-
CommonJS modules cannot be used _directly_ from Java; to this end, any popular package bundlers (such as Parcel, Browserify or Webpack) can be used.
65+
CommonJS modules cannot be used _directly_ from Java; to this end, any popular package bundlers (such as Parcel, Browserify, or Webpack) can be used.
6766

6867
### ECMAScript Modules (ECM)
69-
7068
ECMAScript modules can be loaded in GraalVM JavaScript in the following ways:
7169

7270
1. The support of ECMAScript modules in Node.js is still experimental.
73-
GraalVM supports all features supported by the Node.js version that is compatible with GraalVM.
74-
To check such version, simply run `bin/node --version`.
71+
GraalVM Enterprise supports all features supported by the Node.js version that is compatible with GraalVM.
72+
To check and verify the version, simply run `bin/node --version`.
7573
2. ECMAScript modules can be loaded in a `Context` simply by evaluating the module sources.
7674
Currently, GraalVM JavaScript loads ECMAScript modules based on their file extension.
7775
Therefore, any ECMAScript module must have file name extension `.mjs`.
7876
This might change in future versions of GraalVM JavaScript.
7977

80-
More details about evaluating files using the Context API are available in the [API Javadoc](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Source.html).
78+
More details about evaluating files using the Context API are available in the [javadoc](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Source.html).
8179

8280
### CommonJS Modules (CJS)
83-
8481
CommonJS modules can be loaded in GraalVM JavaScript in the following way:
8582

8683
1. In Node.js, modules can be loaded using the `require()` built-in function, as expected.
8784
2. By default, the `Context` API does not support CommonJS modules, and has no built-in `require()` function.
88-
In order to be loaded and used from a `Context` in Java, a CJS module needs to be _bundled_ into a self-contained JavaScript source file.
89-
This can be done using one of the many popular open-source bundling tools such as Parcel, Browserify and Webpack.
85+
In order to be loaded and used from a `Context` in Java, a CommonJS module needs to be _bundled_ into a self-contained JavaScript source file.
86+
This can be done using one of the many popular open-source bundling tools such as Parcel, Browserify, and Webpack.
9087
Experimental support for CommonJS modules can be enabled through the `js.commonjs-require` option as described below.
9188

9289
#### Experimental support for CommonJS NPM modules in the `Context` API
93-
9490
The `js.commonjs-require` option provides a built-in `require()` function that can be used to load NPM-compatible CommonJS modules in a JavaScript `Context`.
9591
Currently, this is an experimental feature not for production usage.
9692

9793
To enable CommonJS support, a JavaScript context can be created in the following way:
98-
```
94+
```java
9995
Map<String, String> options = new HashMap<>();
10096
// Enable CommonJS experimental support.
10197
options.put("js.commonjs-require", "true");
@@ -118,43 +114,39 @@ Value module = cx.eval("js", "require('some-module');");
118114
```
119115

120116
##### Differences with Node.js built-in `require()` function
121-
122-
The `Context` built-in `require()` function can load regular NPM modules implemented in JavaScript, but cannot load _native_ NPM modules.
123-
The built-in `require()` relies on the [Truffle FileSystem](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html), therefore I/O access needs to be enabled at context creation time using the [`allowIO` option](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Context.Builder.html#allowIO-boolean-).
117+
The `Context` built-in `require()` function can load regular NPM modules implemented in JavaScript, but cannot load native NPM modules.
118+
The built-in `require()` relies on the [FileSystem](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html), therefore I/O access needs to be enabled at context creation time using the [`allowIO` option](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Context.Builder.html#allowIO-boolean-).
124119
The built-in `require()` aims to be largely compatible with Node.js, and we expect it to work with any NPM module that would work in a browser (e.g., created using a package bundler).
125120

126121
##### Installing an NPM module to be used via the `Context` API
127-
128122
In order to be used from a JavaScript `Context`, an NPM module needs to be installed to a local folder.
129123
This can be done using GraalVM JavaScript's `npm install` command like one would normally do for Node.js applications.
130124
At runtime, the option `js.commonjs-require-cwd` can be used to specify the main installation folder for NPM packages.
131125
The `require()` built-in function will resolve packages according to the default Node.js' [package resolution protocol](https://nodejs.org/api/modules.html#modules_all_together) starting from the directory specified via `js.commonjs-require-cwd`.
132126
When no directory is provided with the option, the current working directory of the application will be used.
133127

134128
##### Node.js core modules mockups
135-
136-
Some JavaScript applications or NPM modules might need functionalities that are available in Node.js' built-in modules (e.g., `'fs'`, `'buffer'`, etc.)
129+
Some JavaScript applications or NPM modules might need functionalities that are available in Node.js' built-in modules (e.g., `'fs'` and `'buffer'`, etc.).
137130
Such modules are not available in the `Context` API.
138-
Thankfully, the Node.js community has developed high-quality JavaScript implementations for many Node.js core modules (e.g.,: the ['buffer'](https://www.npmjs.com/package/buffer) module for the browser).
131+
Thankfully, the Node.js community has developed high-quality JavaScript implementations for many Node.js core modules (e.g., the ['buffer'](https://www.npmjs.com/package/buffer) module for the browser).
139132
Such alternative module implementations can be exposed to a JavaScript `Context` using the `js.commonjs-core-modules-replacements` option, in the following way:
133+
```java
134+
options.put("js.commonjs-core-modules-replacements", "buffer:my-buffer-implementation");
140135
```
141-
options.put("js.commonjs-core-modules-replacements",
142-
"buffer:my-buffer-implementation");
143-
```
136+
144137
As the code suggests, the option instructs the GraalVM JavaScript runtime to load a module called `my-buffer-implementation` when an application attempts to load the Node.js `'buffer'` built-in module using `require('buffer')`.
145138

146139
##### Global symbols pre-initialization
147-
148140
An NPM module or a JavaScript application might expect certain global properties to be defined in the global scope.
149141
For example, applications or modules might expect the `Buffer` global symbol to be defined in the JavaScript global object.
150142
The option `js.commonjs-global-properties` can be used to pre-initialize such global symbols using the `Context` API.
151143
The option can be used in the following way:
152-
```
144+
```java
153145
options.put("js.commonjs-global-properties", "./globals.js");
154146
```
155-
Once specified, the file `globals.js` will be loaded at context creation time, that is, before any JavaScript source execution.
147+
Once specified, the file `globals.js` will be loaded at context creation time. That is, before any JavaScript source execution.
156148
An example `globals.js` file might perform the following initialization steps:
157-
```
149+
```java
158150
// define an empty object called 'process'
159151
globalThis.process = {}
160152
// define the 'Buffer' global symbol

0 commit comments

Comments
 (0)