8

我正在尝试让 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( like ./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我想要做的事情的正确路径。不过不确定。

4

1 回答 1

14

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

  1. 您必须确保使用r.js (not require.js) ,这是 rhino 的 require.js 的修改版本。
  2. 你必须扩展ScritableObject类来实现loadprint运行。当你调用 时require(["a"]),会调用这个类中的 load 函数,你可以调整这个函数来从任何位置加载 js 文件。在下面的示例中,我从classpath.
  3. 您必须arguments在示例代码中定义共享范围中的属性,如下所示
  4. 或者,您可以使用 , 来配置子路径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();

  }

}

加载器.js

require.config({
    baseUrl: "js/app"
});

require (["a", "b"], function(a,  b) {
    print('modules loaded');
});

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

于 2012-06-17T23:42:57.723 回答