如何将CommonJS模块与Oracle的新Nashorn JS引擎一起使用?

时间:2013-10-21 16:41:03

标签: commonjs nashorn

我在寻找Nashorn的模块系统。据我所知,CommonJS是关于JS模块的方法。我查看了列表(herehere)并且发现了Java的CommonJS实现方式。

Narwhal不再有效,而且documentation不再托管在GitHub上。是否存在支持Java的现有CommonJS实现,还是应该启动一个新项目?

5 个答案:

答案 0 :(得分:18)

在这里查看jvm-npm https://github.com/nodyn/jvm-npm。该项目由nodyn用作CommonJS模块系统。它是NPM感知的,这意味着您可以直接从NPM加载模块,但它不提供任何Node.js API。

以下是一个简单的示例用法:

$ npm install pegjs
npm http GET https://registry.npmjs.org/pegjs
npm http 200 https://registry.npmjs.org/pegjs
pegjs@0.8.0 node_modules/pegjs
$ jrunscript
nashorn> typeof require
undefined
nashorn> load('./jvm-npm.js')
nashorn> typeof require
function
nashorn> var PEG = require('pegjs');
nashorn> typeof PEG
object

它主要是所有Javascript,但实际从文件系统加载文件等都是使用Java完成的。

答案 1 :(得分:6)

我在Nashorn邮件列表上问了一个非常类似的问题,这是Sundar的(Nashorn工程师)回复:

  

来自:A。Sundararaj an

     

致:nashorn-dev@openjdk.java.net

     

我忘了添加。 Nashorn不包含任何内置模块系统。   但是,如果模块系统是纯JS + Java,则必须能够运行   在nashorn。

     

Nashorn支持“加载”(从URL,文件,资源加载脚本)和   “loadWithNewGlobal”(加载脚本但进入新的全局范围)   除了古老的'eval'之外的原始。所以,它应该是   任何模块系统都可以在nashorn上实现   纯JS或者可能带有一些Java代码。

     

-Sundar

答案 2 :(得分:5)

我一直在寻找这样的实现。我一直在使用Rhino-Require的小补丁版本。虽然Rhino声称与CommonJS兼容,但AFAIK,它只实现了模块而不是包(package.json)无法解析。 RingoJS应该兼容。但Nashorn永远不会是see

稍后,Oracle宣布依赖Avatar.jshere的项目“阿凡达”。这是非正式名为Node.jar的官方项目。但截至目前,你必须自己编译。这个项目很年轻。

另一个非常年轻的项目是Nodyn,它依赖于dyn.js.

所以,如果理解得很好,CommonJs应该使用avatar-js和nodyn,但这两个人还很年轻。我不明白为什么avatar-js与nashorn一起没有完全分发。

一种解决方案是添加一个CommonJS兼容性脚本,例如Rhino的脚本,它添加了importClass / importPackage(mozilla_compat.js),它可以将相同的CommonJS兼容性添加到nashorn中,这种Rhino-Require shim经过了彻底的测试。< / p>

答案 3 :(得分:5)

我有同样的需求,我使用了jvm-npm一段时间,但是我需要一些能够工作的东西,即使不允许在JavaScript中使用Java包,所以我在这里写了我自己的版本:{{3} }

它完全用Java实现,支持从文件系统以外的地方加载模块(Java资源,自定义数据库等)。

如果有人想使用它,它会在Maven Central上发布。

答案 4 :(得分:1)

还有nashorn-require,你也可以从github那里得到它。我已经使用过了,我能够做到

        engine.eval(reader("src/main/javascript/nashorn-require.js"),bindings);
        engine.eval("var initRequire = load('src/main/javascript/nashorn-require.js');",bindings);
        engine.eval("initRequire({mainFile : 'src/main/javascript/foo', debug : true})", bindings);
        engine.eval("var babel = require('babel');",bindings);

然后使用

将JSX React组件转换为ES5
        Buffer input = findTemplateSource(fileLocation,context);
        bindings.put("input",input.toString());
        result = engine.eval("babel.transform(input,{ presets: ['react', 'es2015'] }).code;",bindings);

然后,当我对我的浏览器做出反应并做出反应并加载生成的js组件时,事情运行正常,所以我确信Babel非常高兴,尽管我不确定它是否会找不到第三方插件......