Skip to content

Commit bd029e4

Browse files
authored
Update NodeEmbedding docs (#435)
1 parent 7610664 commit bd029e4

File tree

2 files changed

+41
-50
lines changed

2 files changed

+41
-50
lines changed

docs/features/js-threading-async.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ JavaScript engines have a single-threaded execution model. That means all access
44
data or operations must be performed from the JavaScript thread.
55
(It is possible run multiple JavaScript execution threads in a process using
66
[Web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) or the
7-
[`NodejsEnvironment`](../reference/dotnet/Microsoft.JavaScript.NodeApi.Runtime/NodejsEnvironment)
7+
[`NodeEmbeddingRuntime`](../reference/dotnet/Microsoft.JavaScript.NodeApi.Runtime/NodeEmbeddingRuntime)
88
class, but the thread affinity rules still apply.)
99

1010
## Invalid thread access

docs/scenarios/dotnet-js.md

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,90 +5,81 @@ This functionality is still experimental. It works, but the process is not as st
55
should be.
66
:::
77

8-
## Building the required `libnode` binary
9-
This project depends on a [PR to Node.js](https://github.com/nodejs/node/pull/43542) that adds
10-
simpler ABI-stable embedding APIs to `libnode`. Until that PR is merged, you'll need to build your
11-
own binary from a branch. And even after it's merged, the Node.js project does not currently and
12-
has no plans to publish official `libnode` binaries.
13-
14-
1. Install the [prerequisites for building Node.js](https://github.com/nodejs/node/blob/main/BUILDING.md#building-nodejs-on-supported-platforms).
15-
(On Windows this is basically Python 3 and either VS 2022 or the C++ build tools.)
16-
17-
2. Clone the napi-libnode repo/branch:
18-
19-
```shell
20-
mkdir libnode
21-
cd libnode
22-
git clone https://github.com/jasongin/nodejs -b napi-libnode-v20.9.0 --single-branch .
23-
```
24-
25-
3. Build in shared-library mode:
26-
::: code-group
27-
```shell [Windows]
28-
.\vcbuild.bat x64 release dll openssl-no-asm
29-
```
30-
```shell [Mac / Linux]
31-
./configure --shared; make -j4
32-
```
33-
:::
34-
The build may take an hour or more depending on the speed of your system.
35-
36-
4. A successful build produces a binary in the `out/Release` directory:
37-
- `libnode.dll` (Windows)
38-
- `libnode.dylib` (Mac)
39-
- `libnode.???.so` (Linux)
8+
## Acquiring the the required `libnode` binary
9+
This project depends on a [PR to Node.js](https://github.com/nodejs/node/pull/54660) that adds
10+
simpler ABI-stable embedding APIs to `libnode`. Until that PR is merged and the Node.js project
11+
starts building shared `libnode`, we offer the
12+
[`Microsoft.JavaScript.LibNode](https://www.nuget.org/packages/Microsoft.JavaScript.LibNode) NuGet
13+
package that installs pre-built `libnode` for Windows, MacOSX, and Linux (Ubuntu). This package
14+
depends on the runtime ID specific NuGet packages which can be used directly if needed.
15+
16+
Since the PR for the ABI-stable embedding API is still work in progress, the built `libnode`
17+
will have breaking changes between versions. See the `Directory.Packages.props` file in the
18+
root of the `node-api-dotnet` project for the matching version of the `Microsoft.JavaScript.LibNode`
19+
package.
4020

4121
## Importing JS modules into .NET
4222

43-
1. Load `libnode` and initialize a Node.js "platform" and "environment" instance:
23+
1. Load `libnode` and initialize a Node.js "platform" and "runtime" instance:
4424
```C#
4525
// Find the path to the libnode binary for the current platform.
4626
string baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
4727
string libnodePath = Path.Combine(baseDir, "libnode.dll");
48-
NodejsPlatform nodejsPlatform = new(libnodePath);
49-
var nodejs = nodejsPlatform.CreateEnvironment(baseDir);
28+
NodeEmbeddingPlatform nodejsPlatform = new(libnodePath, null);
29+
NodeEmbeddingThreadRuntime nodejsRuntime = nodejsPlatform.CreateThreadRuntime(baseDir,
30+
new NodeEmbeddingRuntimeSettings
31+
{
32+
MainScript =
33+
"globalThis.require = require('module').createRequire(process.execPath);\n"
34+
});
5035
```
5136

52-
There can only be one `NodejsPlatform` instance per process, so typically it would be stored
53-
in a static variable. From the platform, multiple `NodejsEnvironment` instances may be created
54-
and disposed.
37+
There can only be one
38+
[`NodeEmbeddingPlatform`](../reference/dotnet/Microsoft.JavaScript.NodeApi.Runtime/NodeEmbeddingPlatform)
39+
instance per process, so typically it would be stored in a static variable. From the platform,
40+
multiple
41+
[`NodeEmbeddingRuntime`](../reference/dotnet/Microsoft.JavaScript.NodeApi.Runtime/NodeEmbeddingRuntime)
42+
or
43+
[`NodeEmbeddingThreadRuntime`](../reference/dotnet/Microsoft.JavaScript.NodeApi.Runtime/NodeEmbeddingThreadRuntime)
44+
instances may be created and disposed.
5545

56-
The directory provided to the environment instance is the base for package resolution. Any packages
57-
or modules imported in the next step must be installed (in a `node_modules` directory) in that base
58-
directory or a parent directory.
46+
The directory provided to the
47+
[`NodeEmbeddingThreadRuntime`](../reference/dotnet/Microsoft.JavaScript.NodeApi.Runtime/NodeEmbeddingThreadRuntime)
48+
instance is the base for package resolution. Any packages or modules imported in the next step must
49+
be installed (in a `node_modules` directory) in that base directory or a parent directory.
5950

6051
2. Invoke a simple script from C#:
6152
```C#
62-
await nodejs.RunAsync(() =>
53+
await nodejsRuntime.RunAsync(() =>
6354
{
6455
JSValue.RunScript("console.log('Hello from JS!');");
6556
});
6657
```
6758

6859
Be aware of JavaScript's single-threaded execution model. **All JavaScript operations must be
6960
performed from the JS environment thread**, unless otherwise noted. Use any of the `Run()`,
70-
`RunAsync()`, `Post()`, or `PostAsync()` methods on the JS environment instance to switch to the
71-
JS thread. Also keep in mind any JavaScript values of type `JSValue` (or any of the more specific
72-
JS value struct types) are not valid after switching off the JS thread. A `JSReference` can hold
73-
on to a JS value for future use. See also
61+
`RunAsync()`, `Post()`, or `PostAsync()` methods on the JS `NodeEmbeddingThreadRuntime` instance
62+
to switch to the JS thread. Also keep in mind any JavaScript values of type `JSValue` (or any of
63+
the more specific JS value struct types) are not valid after switching off the JS thread.
64+
A `JSReference` can hold on to a JS value for future use. See also
7465
[JS Threading and Async Continuations](../features/js-threading-async) and
7566
[JS References](../features/js-references).
7667

7768
3. Import modules or module properties:
7869
```C#
7970
// Import * from the `fluid-framework` module. Items exported from the module will be
8071
// available as properties on the returned JS object.
81-
JSValue fluidPackage = nodejs.Import("fluid-framework");
72+
JSValue fluidPackage = nodejsRuntime.Import("fluid-framework");
8273

8374
// Import just the `SharedString` class from the `fluid-framework` module.
84-
JSValue sharedStringClass = nodejs.Import("fluid-framework", "SharedString");
75+
JSValue sharedStringClass = nodejsRuntime.Import("fluid-framework", "SharedString");
8576
```
8677
As explained above, importing modules must be done on the JS thread.
8778

8879
## Debugging the JavaScript code in a .NET process
8980
```C#
9081
int pid = Process.GetCurrentProcess().Id;
91-
Uri inspectionUri = nodejs.StartInspector();
82+
Uri inspectionUri = nodejsRuntime.StartInspector();
9283
Debug.WriteLine($"Node.js ({pid}) inspector listening at {inspectionUri}");
9384
```
9485
Then attach a JavaScript debugger such as VS Code or Chrome to the inspection URI.

0 commit comments

Comments
 (0)