使用require.js和Java / Rhino解析模块 [英] Resolving modules using require.js and Java/Rhino

查看:131
本文介绍了使用require.js和Java / Rhino解析模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to get require.js to load modules on the server-side with Java 6 and Rhino.

我可以加载require.js本身就好。 Rhino可以看到 require()函数。我可以告诉,因为当我将 require()更改为 requireffdkj()

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().

但是当我试图要求一个简单的JS时,比如 hello.js

But when I try to require even a simple JS, like 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 我觉得它可能去的地方,包括我的硬盘根,我的用户目录的根目录,我的目录没有任何作用。

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.

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

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.

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

Any suggestions? Can I even use require.js from Rhino?

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

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:

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 是我正在尝试做的正确路径。但不确定。

"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.

推荐答案

require.js适用于rhino。最近,我在一个项目中使用它。

require.js works well with rhino. Recently, I used it in a project.


  1. 你必须确保使用 r.js (不是require.js),rhino的require.js的修改版本。

  2. 你必须扩展 ScritableObject 类来实现加载打印函数。当你调用 require([a])时,将调用此类中的load函数,你可以调整这个函数来从任何位置加载js文件。在下面的示例中,我从 classpath 加载。

  3. 您必须定义属性 arguments 在sharedscope中,如下面的示例代码所示

  4. 或者,您可以使用 require.config配置子路径 ,指定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 ScritableObject class to implement load and print function. 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 arguments in 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.

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 目录应该在你的classpath。

js/app directory should be in your classpath.

这篇关于使用require.js和Java / Rhino解析模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆