我正在为 Nashorn 寻找一个模块系统。据我所知,CommonJS 是涉及 JS 模块的方法。我查看了列表(此处和此处),几乎没有发现 Java 的 CommonJS 实现方式。
Narwhal不再活跃,它的文档不再托管在 GitHub 上。是否有支持 Java 的现有 CommonJS 实现,或者我应该开始一个新项目?
在这里查看 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 完成的。
不久前,我在 Nashorn 邮件列表上问了一个非常相似的问题,这是 Sundar(Nashorn 工程师)的回复:
来自:A. Sundararajan
收件人:nashorn-dev@openjdk.java.net
我忘了补充。Nashorn 不包含任何内置模块系统。但是,如果一个模块系统是纯 JS + Java 的,那么它必须可以在 nashorn 上运行。
除了旧的“eval”之外,Nashorn 还支持“load”(从 URL、文件、资源加载脚本)和“loadWithNewGlobal”(将脚本加载到新的全局范围内)原语。因此,任何模块系统都应该可以在纯 JS 或一些 Java 代码的 nashorn 之上实现。
-桑达
我一直在寻找这样的实现。我一直在使用Rhino-Require的一个小补丁版本。尽管 Rhino 声称与 CommonJS 兼容,但 AFAIK,它只实现了模块而不是包(package.json)无法解析。 RingoJS应该是兼容的。但 Nashorn 将永远不会被看到。
后来,Oracle 宣布了依赖Avatar.js或here的项目 Avatar 。它是非官方称为 Node.jar 的官方项目。但是到目前为止,您必须自己编译它。该项目非常年轻。
另一个非常年轻的项目是Nodyn,它依赖于 dyn.js。
所以,如果理解得好,CommonJs 应该与 avatar-js 和 nodyn 一起工作,但这两个还很年轻。我不明白为什么 avatar-js 没有与 nashorn 一起完全分布。
一种解决方案是添加一个 CommonJS 兼容性脚本,就像 Rhino 的那样,它添加了 importClass/importPackage ( mozilla_compat.js ),它将 CommonJS 兼容性添加到 nashorn 中,一种 Rhino-Require shim 彻底测试。
我有同样的需求,我使用了jvm-npm一段时间,但我需要一些即使不允许在 JavaScript 中使用 Java 包也能工作的东西,所以我在这里编写了自己的版本:https ://github.com/coveo /nashorn-commonjs-modules
它完全用 Java 实现,支持从文件系统以外的其他地方加载模块(Java 资源、自定义数据库等)
如果有人想使用它,它会在 Maven Central 上发布。
还有 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);
然后,当我将 react 和 react-dom 拉到浏览器中并加载生成的 js 组件时,一切正常,所以我确信 Babel 非常高兴,尽管我不确定它是否会找到 3rd-party 插件...