使用require.js和Java / Rhino解析模块

我正在尝试让require.js在服务器端使用Java 6和Rhino加载模块。

我能够自己加载require.js就好了。 Rhino可以看到require()函数。 我可以告诉,因为当我将require()更改为requireffdkj()类的东西时,Rhino抱怨它无法找到该函数。

但是当我尝试甚至需要一个简单的JS时,比如hello.js

 var hello = 'hello'; 

使用以下任一方法:

 require('hello'); require('./hello'); 

它不起作用。 我明白了

 Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.JavaScriptException: [object Error] (#31) in  at line number 31 at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:153) at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:167) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247) 

我在Java类路径的顶部有我的hello.js . 这也是我需要的地方require.js 。 我尝试将hello.js移动hello.js我认为可能发生的任何地方,包括我的硬盘驱动器的根目录,用户目录的根目录,运行Java应用程序的目录等等。没有任何作用。

我查看了CommonJS规范( http://wiki.commonjs.org/wiki/Modules/1.0 ),它说顶级ID(如hello )是从“概念模块名称空间根”解析的,而相对ID (如./hello )是针对调用模块解决的。 我不确定这些基线在哪里,我怀疑这是问题所在。

有什么建议么? 我甚至可以使用Rhino的require.js吗?

编辑:我认为我需要根据Pointy的建议在下面的评论中设置环境,我也尝试评估r.js (我在评估require.js之后尝试进行评估,然后在require.js之前再次进行require.js 。)在任何一种情况下我都会收到错误:

 Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "arguments" is not defined. (#19) in  at line number 19 at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:153) at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:167) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247) 

“arguments”似乎是r.js一个变量。 我认为这是针对命令行参数的,所以我不认为r.js是我正在尝试做的正确路径。 不过不确定。

require.js与rhino配合得很好。 最近,我在一个项目中使用它。

  1. 你必须确保使用r.js (不是require.js),修改版本的require.js用于rhino。
  2. 您必须扩展ScritableObject类以实现loadprintfunction。 当你调用require(["a"]) ,将调用此类中的load函数,你可以调整这个函数来从任何位置加载js文件。 在下面的示例中,我从classpath加载。
  3. 您必须在sharedscope中定义属性arguments ,如示例代码中所示
  4. (可选)您可以使用require.config配置子路径,以指定js文件所在的类路径中的子目录。

JsRuntimeSupport

 public class JsRuntimeSupport extends ScriptableObject { private static final long serialVersionUID = 1L; private static Logger logger = Logger.getLogger(JsRuntimeSupport.class); private static final boolean silent = false; @Override public String getClassName() { return "test"; } public static void print(Context cx, Scriptable thisObj, Object[] args, Function funObj) { if (silent) return; for (int i = 0; i < args.length; i++) logger.info(Context.toString(args[i])); } public static void load(Context cx, Scriptable thisObj, Object[] args, Function funObj) throws FileNotFoundException, IOException { JsRuntimeSupport shell = (JsRuntimeSupport) getTopLevelScope(thisObj); for (int i = 0; i < args.length; i++) { logger.info("Loading file " + Context.toString(args[i])); shell.processSource(cx, Context.toString(args[i])); } } private void processSource(Context cx, String filename) throws FileNotFoundException, IOException { cx.evaluateReader(this, new InputStreamReader(getInputStream(filename)), filename, 1, null); } private InputStream getInputStream(String file) throws IOException { return new ClassPathResource(file).getInputStream(); } } 

示例代码

 public class RJsDemo { @Test public void simpleRhinoTest() throws FileNotFoundException, IOException { Context cx = Context.enter(); final JsRuntimeSupport browserSupport = new JsRuntimeSupport(); final ScriptableObject sharedScope = cx.initStandardObjects(browserSupport, true); String[] names = { "print", "load" }; sharedScope.defineFunctionProperties(names, sharedScope.getClass(), ScriptableObject.DONTENUM); Scriptable argsObj = cx.newArray(sharedScope, new Object[] {}); sharedScope.defineProperty("arguments", argsObj, ScriptableObject.DONTENUM); cx.evaluateReader(sharedScope, new FileReader("./r.js"), "require", 1, null); cx.evaluateReader(sharedScope, new FileReader("./loader.js"), "loader", 1, null); Context.exit(); } } 

loader.js

 require.config({ baseUrl: "js/app" }); require (["a", "b"], function(a, b) { print('modules loaded'); }); 

js/app目录应该在你的类路径中。