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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 12:01:30  来源:igfitidea点击:

Resolving modules using require.js and Java/Rhino

javajavascriptrequirerequirejsrhino

提问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.jsat the top of the Java classpath. That's where I have require.jsas well. I tried moving hello.jseverywhere 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.jsas 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.jsis 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 适用于犀牛。最近,我在一个项目中使用了它。

  1. You have to make sure to use r.js(not require.js) , modified version of require.js for rhino.
  2. You have to extend ScritableObjectclass to implement loadand printfunction. When you call require(["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 from classpath.
  3. You have to define the property argumentsin the sharedscope as shown below in the sample code
  4. Optionally, you can configure the sub path using require.config, to specify the subdirectory inside classpath where js files are located.
  1. 你必须确保使用r.js(not require.js) ,修改版本的 require.js for rhino。
  2. 您必须扩展ScritableObject类才能实现loadprint运行。当您调用 时require(["a"]),该类中的加载函数将被调用,您可以调整该函数以从任何位置加载 js 文件。在下面的示例中,我从classpath.
  3. 您必须arguments在 sharedscope 中定义属性,如下面的示例代码所示
  4. 或者,您可以使用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/appdirectory should be in your classpath.

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