From 5c0e36e48baaa1c7008715bff7753b186147c9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobi=20Sch=C3=A4fer?= Date: Sat, 17 Dec 2016 10:36:13 +0100 Subject: [PATCH] add: experimental support for commonjs modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit activated rhino’s require() method and module.exports object; both work, but the default implementation cannot load packages which in turn require modules in relative subdirs. a new property called commonjs.dir can be used to define an additional search directory. the app dir is added automatically. --- src/helma/scripting/rhino/PathWrapper.java | 2 +- src/helma/scripting/rhino/RhinoCore.java | 34 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/helma/scripting/rhino/PathWrapper.java b/src/helma/scripting/rhino/PathWrapper.java index 7a86cab4..406c615f 100644 --- a/src/helma/scripting/rhino/PathWrapper.java +++ b/src/helma/scripting/rhino/PathWrapper.java @@ -35,7 +35,7 @@ public class PathWrapper extends ScriptableObject { /** * Zero arg constructor for creating the PathWrapper prototype. */ - public PathWrapper (RhinoCore core) throws PropertyException, NoSuchMethodException { + public PathWrapper (RhinoCore core) throws RhinoException, NoSuchMethodException { this.core = core; // create a dummy path object this.path = new RequestPath(core.app); diff --git a/src/helma/scripting/rhino/RhinoCore.java b/src/helma/scripting/rhino/RhinoCore.java index 49cd229c..46c1d57f 100644 --- a/src/helma/scripting/rhino/RhinoCore.java +++ b/src/helma/scripting/rhino/RhinoCore.java @@ -25,6 +25,7 @@ import helma.objectmodel.db.DbMapping; import helma.objectmodel.db.NodeHandle; import helma.scripting.*; import helma.util.*; + import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextAction; import org.mozilla.javascript.ContextFactory; @@ -42,9 +43,12 @@ import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Undefined; import org.mozilla.javascript.WrapFactory; import org.mozilla.javascript.Wrapper; +import org.mozilla.javascript.commonjs.module.RequireBuilder; +import org.mozilla.javascript.commonjs.module.provider.*; import org.mozilla.javascript.tools.debugger.ScopeProvider; import java.io.*; +import java.net.URI; import java.text.*; import java.util.*; import java.lang.ref.WeakReference; @@ -89,9 +93,9 @@ public final class RhinoCore implements ScopeProvider { // optimization level for rhino engine, ranges from -1 to 9 int optLevel = 0; - // language version - default to JS 1.7 - int languageVersion = 170; - + // language version - default to JS 1.8 + int languageVersion = 180; + // debugger/tracer flags boolean hasDebugger = false; boolean hasTracer = false; @@ -157,6 +161,27 @@ public final class RhinoCore implements ScopeProvider { global.initStandardObjects(context, false); global.init(); + // Enable loading and exporting of CommonJS modules with require and module.exports, resp. + // Inspiration: http://stackoverflow.com/a/30355409/5281580 + + List commonJsPaths = new ArrayList(); + commonJsPaths.add(app.getAppDir().toURI()); + String commonJsAppPath = app.getProperty("commonjs.dir"); + + if (commonJsAppPath != null) { + File commonJsAppDir = new File(app.getAppDir(), commonJsAppPath); + if (commonJsAppDir.isDirectory()) { + commonJsPaths.add(commonJsAppDir.toURI()); + } + } + + new RequireBuilder() + .setModuleScriptProvider(new StrongCachingModuleScriptProvider( + new UrlModuleSourceProvider(commonJsPaths, null))) + .setSandboxed(true) + .createRequire(context, global) + .install(global); + pathProto = new PathWrapper(this); hopObjectProto = HopObject.init(this); @@ -816,7 +841,7 @@ public final class RhinoCore implements ScopeProvider { } } return props; - } + } /** * Get the RhinoCore instance associated with the current thread, or null @@ -1207,6 +1232,7 @@ public final class RhinoCore implements ScopeProvider { } else { app.logError("Unsupported rhino.languageVersion: " + languageVersion); } + // Set up visual debugger if rhino.debug = true if (hasDebugger) initDebugger(cx);