使用require.js和Java / Rhino解析模块

时间:2012-06-17 21:15:05

标签: java javascript require requirejs rhino

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

我能够自己加载require.js就好了。 Rhino可以看到require()函数。我可以说,因为当我将require()更改为requireffdkj()之类的其他内容时,Rhino会抱怨它无法找到该功能。

但是当我试图要求一个简单的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应用程序的目录等等。没有任何作用。< / p>

我看着CommonJS的规格(http://wiki.commonjs.org/wiki/Modules/1.0),并将其说,顶层的ID(例如hello)是从“概念性模块名字空间根”解决,而相对ID(例如{针对调用模块解析{1}})。我不确定这些基线在哪里,我怀疑这是问题。

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

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

require.js

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

1 个答案:

答案 0 :(得分:13)

require.js与rhino配合得很好。最近,我在一个项目中使用它。

  1. 你必须确保使用r.js(不是require.js),修改版本的require.js for rhino。
  2. 您必须扩展ScritableObject类才能实现loadprint功能。当您调用require(["a"])时,将调用此类中的加载函数,您可以调整此函数以从任何位置加载js文件。在下面的示例中,我从classpath
  3. 加载
  4. 您必须在sharedscope中定义属性arguments,如示例代码中所示
  5. 或者,您可以使用require.config配置子路径,以指定js文件所在的类路径中的子目录。
  6. <强> 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目录应该在您的类路径中。