javascript 使用 require.js 和 Java/Rhino 解析模块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11074836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resolving modules using require.js and Java/Rhino
提问by sperumal
I'm trying to get require.js to load modules on the server-side with Java 6 and Rhino.
我正在尝试让 require.js 使用 Java 6 和 Rhino 在服务器端加载模块。
I'm able to load require.js itself just fine. Rhino can see the require()
function. I can tell because Rhino complains that it can't find the function when I change require()
to something else like requireffdkj()
.
我能够加载 require.js 本身就好了。犀牛可以看到这个require()
功能。我可以说是因为 Rhino 抱怨当我更改require()
为requireffdkj()
.
But when I try to require even a simple JS, like hello.js
但是当我尝试甚至需要一个简单的 JS 时,比如 hello.js
var hello = 'hello';
using either of the following:
使用以下任一方法:
require('hello');
require('./hello');
it doesn't work. I get
它不起作用。我得到
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)
I have my hello.js
at the top of the Java classpath. That's where I have require.js
as well. I tried moving hello.js
everywhere I could think it might possibly go, including the root of my hard drive, the root of my user directory, the directory from which I'm running my Java app, etc. Nothing works.
我hello.js
在 Java 类路径的顶部有我的。这也是我的地方require.js
。我尝试移动到hello.js
我认为可能移动的任何地方,包括我的硬盘驱动器的根目录、我的用户目录的根目录、我运行 Java 应用程序的目录等。没有任何效果。
I looked at the CommonJS spec (http://wiki.commonjs.org/wiki/Modules/1.0) and it says that top-level IDs (like hello
) are resolved from the "conceptual module name space root", whereas relative IDs (like ./hello
) are resolved against the calling module. I'm not sure where either of those baselines is, and I suspect that's the issue.
我查看了 CommonJS 规范(http://wiki.commonjs.org/wiki/Modules/1.0),它说顶级 ID(如hello
)是从“概念模块名称空间根”解析的,而相对 ID(像./hello
) 是针对调用模块解决的。我不确定这些基线中的任何一个在哪里,我怀疑这就是问题所在。
Any suggestions? Can I even use require.js from Rhino?
有什么建议?我什至可以使用来自 Rhino 的 require.js 吗?
EDIT:Thinking that I need to set the environment up as per Pointy's suggestion in the comment below, I tried evaluating r.js
as well. (I tried evaluating after evaluating require.js
, and then again before require.js
.) In either case I get an error:
编辑:认为我需要按照 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)
"arguments" appears to be a variable in r.js
. I think it's for command line arguments, so I don't think r.js
is the right path for what I'm trying to do. Not sure though.
“参数”似乎是r.js
. 我认为这是用于命令行参数,所以我认为r.js
这不是我想要做的事情的正确途径。虽然不确定。
回答by sperumal
require.js works well with rhino. Recently, I used it in a project.
require.js 适用于犀牛。最近,我在一个项目中使用了它。
- You have to make sure to use r.js(not require.js) , modified version of require.js for rhino.
- You have to extend
ScritableObject
class to implementload
andprint
function. When you callrequire(["a"])
, the load function in this class will be called, you can tweak this function to load the js file from any location. In the below example, I load fromclasspath
. - You have to define the property
arguments
in the sharedscope as shown below in the sample code - Optionally, you can configure the sub path using
require.config
, to specify the subdirectory inside classpath where js files are located.
- 你必须确保使用r.js(not require.js) ,修改版本的 require.js for rhino。
- 您必须扩展
ScritableObject
类才能实现load
和print
运行。当您调用 时require(["a"])
,该类中的加载函数将被调用,您可以调整该函数以从任何位置加载 js 文件。在下面的示例中,我从classpath
. - 您必须
arguments
在 sharedscope 中定义属性,如下面的示例代码所示 - 或者,您可以使用
require.config
,配置子路径,以指定 js 文件所在的 classpath 中的子目录。
JsRuntimeSupport
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();
}
}
Sample Code
示例代码
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
加载器.js
require.config({
baseUrl: "js/app"
});
require (["a", "b"], function(a, b) {
print('modules loaded');
});
js/app
directory should be in your classpath.
js/app
目录应该在你的类路径中。