我正在尝试让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] (<Unknown source>#31) in <Unknown source> 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)
我的hello.js
位于Java类路径的顶部。这也是我require.js
的地方。我尝试将hello.js
移动到我认为可能发生的任何地方,包括我的硬盘驱动器的根目录,用户目录的根目录,我运行Java应用程序的目录等等。没有任何作用。< / p>
我看着CommonJS的规格(http://wiki.commonjs.org/wiki/Modules/1.0),并将其说,顶层的ID(例如hello
)是从“概念性模块名字空间根”解决,而相对ID(例如{针对调用模块解析{1}})。我不确定这些基线在哪里,我怀疑这是问题。
有什么建议吗?我甚至可以使用Rhino的require.js吗?
编辑:根据下面评论中Pointy的建议,我认为我需要设置环境,我也尝试评估r.js
。 (我在评估./hello
之后尝试评估,然后在require.js
之前再次进行评估。)在任何一种情况下我都会收到错误:
require.js
“arguments”似乎是Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "arguments" is not defined. (<Unknown source>#19) in <Unknown source> 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)
中的变量。我认为这是针对命令行参数的,所以我不认为r.js
是我正在尝试做的正确路径。但不确定。
答案 0 :(得分:13)
require.js与rhino配合得很好。最近,我在一个项目中使用它。
ScritableObject
类才能实现load
和print
功能。当您调用require(["a"])
时,将调用此类中的加载函数,您可以调整此函数以从任何位置加载js文件。在下面的示例中,我从classpath
。arguments
,如示例代码中所示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
目录应该在您的类路径中。