Tech Blog Menu

Tech Blog

Adding support for 'require' in Nashorn


Some parts of Coveo’s query pipeline are extensible using JavaScript. We initially used DynJS, but since it’s now unmaintained, we had to switch to a new JS engine, namely Nashorn that comes out-of-the-box starting with Java 8. Nashorn works pretty well, but it’s missing built-in support for the require function that is used with CommonJS modules. Since it’s a pretty handy feature, we have decided to open source it and publish it on Maven Central.

Using it is pretty straightforward: you simply need to call the Require.enable method in your Java code, passing it your instance of NashornScriptEngine as well as an implementation of a special interface called Folder, responsible of loading JavaScript files from the backing medium of your choice. Here is an example:

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

Pretty simple, right? Once this is done you can use require in your JavaScript code, just as you would within NodeJS:

var foo = require('./foo.js');

As for loading files, we provide out-of-the-box implementations for using the filesystem and Java resources. Providing your own is a straightforward process — as an example, here at Coveo we use one that is backed by an SQL database.

As far as I know, the library fully implements the NodeJS API for loading modules (as described here). It even supports loading modules from the node_modules folder and subfolders, so you can use npm to download libraries and their dependencies. Of course, Nashorn doesn’t support the Node APIs so most modules simply won’t work, but you can still use it to download portable libraries such as Underscore.