问题描述
require.js在rhino上运行良好。最近,我在一个项目中使用了它。
- 您必须确保使用r.js(不是require.js),犀牛的require.js的修改版本。
- 您必须扩展
ScritableObject
类才能实现load
和print
运行。调用时require(["a"])
,将调用此类中的load函数,您可以调整此函数以从任何位置加载js文件。在以下示例中,我从加载classpath
。 - 您必须
arguments
在sharedscope中定义属性,如下面的示例代码所示 - (可选)您可以使用配置子路径
require.config
,以指定classpath内js文件所在的子目录。
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();
}
}
require.config({
baseUrl: "js/app"
});
require (["a", "b"], function(a, b) {
print('modules loaded');
});
js/app
目录应该在您的类路径中。
解决方法
我正在尝试让require.js在Java 6和Rhino的服务器端加载模块。
我能够加载require.js本身就好。Rhino可以看到该require()
功能。我之所以说是因为Rhino抱怨说,当我改成其他require()
东西时,它找不到该功能requireffdkj()
。
但是当我尝试甚至需要一个简单的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应用程序的目录等,但没有任何效果。
我查看了CommonJS规范(http://wiki.commonjs.org/wiki/Modules/1.0),它说顶级ID(如hello
)是从“概念模块名称空间根”解析的,而相对ID(即像./hello
)针对调用模块进行解析。我不确定这两个基准在哪里,我怀疑这就是问题所在。
有什么建议?我什至可以使用Rhino的require.js吗?
编辑:
认为我需要根据以下注释中Pointy的建议设置环境,因此我也尝试进行评估r.js
。(我尝试先进行评估require.js
,然后再进行评估require.js
。)在两种情况下,我都会遇到错误:
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
。我认为这是用于命令行参数的,所以我认为r.js
这不是我尝试执行的正确方法。虽然不确定。