Skip to content

CommonJS modules support for Nashorn, Rhino and Graal.js

License

Notifications You must be signed in to change notification settings

JessHolle/jsr223-commonjs-modules

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CommonJS Modules Support for Nashorn, Rhino and Graal.js

Build Status license Maven JitPack Maven Central

This library adds support for CommonJS modules (aka require) inside a Nashorn, Rhino and Graal.js script engines. It is based on the specification for NodeJS modules and it supports loading modules from the node_modules folder just as Node does. Of course, it doesn't provide an implementation for Node's APIs, so any module that depends on those won't work.

This project is a fork of nashorn-commonjs-modules.

Supported features

  • Ready for use in scripting engines Nashorn, Rhino and Graal.js.
  • Displays the file name and line number in the error stacktrace.
  • Compatible with JSR-223 standard.
  • Implementation on pure Java.
  • No dependency on third-party libraries.

Getting the library using Maven

Add this dependency to your pom.xml to reference the library:

<dependency>
    <groupId>com.github.a-langer</groupId>
    <artifactId>jsr223-commonjs-modules</artifactId>
    <version>1.0.1</version>
</dependency>

Usage

Enabling require in Nashorn script engine:

<!-- Dependency need only for JDK 15 and later -->
<dependency>
    <groupId>org.openjdk.nashorn</groupId>
    <artifactId>nashorn-core</artifactId>
    <version>15.3</version>
</dependency>
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Require.enable(engine, myRootFolder);

Enabling require in Rhino script engine:

<dependency>
    <groupId>cat.inspiracio</groupId>
    <artifactId>rhino-js-engine</artifactId>
    <version>1.7.10</version>
</dependency>
<dependency>
    <groupId>org.mozilla</groupId>
    <artifactId>rhino</artifactId>
    <version>1.7.14</version>
</dependency>
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
Require.enable(engine, myRootFolder);

Enabling require in Graal.js script engine:

<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js-scriptengine</artifactId>
    <version>22.0.0.2</version>
</dependency>
<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js</artifactId>
    <version>22.0.0.2</version>
</dependency>
System.setProperty("jvm.Dtruffle.js.NashornJavaInterop", "true");
System.setProperty("polyglot.js.nashorn-compat", "true");
ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
Require.enable(engine, myRootFolder);

This will expose a new global require function at the engine scope. Any code that is then run using this engine can make use of require.

The second argument specifies the root Folder from which modules are made available. Folder is an interface exposing a few calls that need to be implemented by backing providers to enable loading files and accessing subfolders. Out-of-the-box, the library supports loading modules from the filesystem and from Java resources.

Loading modules from the filesystem

Use the FilesystemFolder.create method to create an implementation of Folder rooted at a particular location in the filesystem:

FilesystemFolder rootFolder = FilesystemFolder.create(new File("/path/to/my/folder"), "UTF-8");
Require.enable(engine, rootFolder);

You need to specify the encoding of the files. Most of the time UTF-8 will be a reasonable choice.

The resulting folder is rooted at the path you specified, and JavaScript code won't be able to "escape" that root by using ../../... In other words, it behaves as is the root folder was the root of the filesystem.

Loading modules from Java resources

Use the ResourceFolder.create method to create an implementation of Folder backed by Java resources:

ResourceFolder rootFolder = ResourceFolder.create(getClass().getClassLoader(), "com/github/alanger/commonjs_modules/test1", "UTF-8");
Require.enable(engine, rootFolder);

As for ResourceFolder, you need to specify the encoding for the files that are read.

Related repositories

About

CommonJS modules support for Nashorn, Rhino and Graal.js

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 99.3%
  • JavaScript 0.7%