Knowledgebase: MarkLogic Server
Server-side JavaScript implementation and module reuse
11 February 2015 02:20 PM

Introduction

This article discusses how JavaScript is implemented in MarkLogic Server, and how can modules be reused?

Is Node.js embedded in the server?

MarkLogic 8 embeds Google's V8 JavaScript engine, just like Node.js does, but not Node.js itself. Both environments use JavaScript and share the core set of types, functions, and objects that are defined in the language. However, they provide completely different contexts.

Can I reuse code written for Node in Server-Side JavaScript?

Not all JavaScript that runs in the browser will work in Node.js; Similarly, not all JavaScript that runs in Node.js will work in MarkLogic. JavaScript that doesn’t depend on the specific environment is portable between MarkLogic, Node.js, and even the browser.

For example, the utility lodash library can run in any environment because it only depends on features of JavaScript, not the particular environment in which it’s running.

Conversely, Node’s HTTP library is not available in MarkLogic because that library is particular to JavaScript running in Node.js, not built-in to the language. (To get the body of an HTTP request in MarkLogic, for example, you’d use the xdmp.getRequestBody() function, part of MarkLogic’s built-in HTTP server library.) If you’re looking to use Node with MarkLogic, we provide a full-featured, open-source client API.

Will you allow npm modules on MarkLogic?

JavaScript libraries that don’t depend on Node.js should work just fine, but you cannot use npm directly today to manage server-side JavaScript modules in MarkLogic. (This is something that we’re looking at for a future release.)

To use external JavaScript libraries in MarkLogic, you need to copy the source to a directory under an app server’s modules root and point to them with a require() invocation in the importing module.

What can you import?

JavaScript modules

Server-side JavaScript in MarkLogic implements a module system similar to CommonJS. A library module exports its public types, variables, and functions. A main module requires a library module, binding the exported types, variables, and functions to local “namespace” global variables. The syntax is very similar to the way Node.js manages modules. One key difference is that modules are only scoped for a single request and do not maintain state beyond that request. In Node, if you change the state of a module export, that change is reflected globally for the life of the application. In MarkLogic, it’s possible to change the state of a library module, but that state will only exist in the scope of a single request.

For example:

// *********************************************
// X.sjs

module.exports.blah = function() {
    return "Not Math.random";
}

// *********************************************
// B.sjs

var x = require("X.sjs");

function bTest() {
    return x.blah === Math.random;
}

module.exports.test = bTest;

// *********************************************
// A.sjs

var x = require("X.sjs");
var b = require("B.sjs");

x.blah = Math.random;

b.test();

// *********************************************
// A-prime.sjs

var x = require("X.sjs");
var b = require("B.sjs");

b.test();

Invoking A.sjs returns true, but subsequently invoking A-prime.sjs still returns false.


XQuery modules

MarkLogic also allows server-side JavaScript modules to import library modules written in XQuery and call the exported variables and functions as if they were JavaScript.

 

(2 vote(s))
Helpful
Not helpful

Comments (0)