Как я могу использовать модули CommonJS с новым Nashorn JS Engine от Oracle?

Я ищу модульную систему для Nashorn. Из того, что я могу сказать, CommonJS - это путь к модулям для JS. Я просмотрел список (здесь и здесь) и не нашли ничего на пути реализации CommonJS для Java.

Narwhal больше не активен и documentation больше не размещается на GitHub. Существует ли существующая реализация CommonJS, которая поддерживает Java, или я должен начать новый проект?

Ответ 1

Я задал очень похожий вопрос в списке рассылки Nashorn некоторое время назад, здесь Сундар (инженер Нашорна) ответил:

От: A. Sundararaj an

Кому: [email protected]

Я забыл добавить. Nashorn не содержит встроенной модульной системы. Но если модульная система является чистой JS + Java, она должна быть доступна на nashorn.

Nashorn поддерживает "загрузку" (загружает скрипты из URL, файла, ресурсов) и "loadWithNewGlobal" (загружает script, но в новую глобальную область) примитивы в дополнение к добрым старым "eval". Таким образом, это должно быть возможно, для любой модульной системы, которая будет реализована поверх nashorn в чистый JS или, возможно, с небольшим количеством кода Java.

-Sundar

Ответ 2

Посмотрите на jvm-npm здесь https://github.com/nodyn/jvm-npm. Этот проект используется nodyn как система модулей CommonJS. Это NPM-aware, то есть вы можете загружать модули непосредственно из NPM, но он не предоставляет никакого API Node.js.

Вот простой пример использования:

$ npm install pegjs
npm http GET https://registry.npmjs.org/pegjs
npm http 200 https://registry.npmjs.org/pegjs
[email protected] 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.

Ответ 3

Я искал такую ​​реализацию некоторое время. Я использовал небольшую исправленную версию Rhino-Require. Хотя Rhino утверждал, что совместим с CommonJS, AFAIK, он реализовал только модули, а не пакеты (package.json) не может быть проанализирован. RingoJS должен быть совместимым. Но Nashorn никогда не будет см..

Позднее Oracle анонсировала проект Avatar, который опирается на Avatar.js или здесь. Это официальный проект того, что неофициально называлось Node.jar. Но на данный момент вы должны скомпилировать его самостоятельно. Проект очень молод.

Еще один очень молодой проект Nodyn, который зависит от dyn.js.

Итак, если понимать хорошо, CommonJs должен работать с аватаром-js и nodyn, но эти двое еще довольно молоды. Я не понимаю, почему аватар-js не полностью распределен вместе с nashorn.

Одним из решений было бы добавить совместимость с CommonJS script, как и для Rhino, которая добавляет importClass/importPackage (mozilla_compat.js), который добавит CommonJS совместимость с nashorn, тип протеза Rhino-Require тщательно протестирован.

Ответ 4

У меня была такая же потребность, и я некоторое время использовал jvm-npm, но мне нужно было что-то, что могло бы работать даже без разрешения использования Java-пакеты внутри JavaScript, поэтому я написал свою собственную версию здесь: https://github.com/coveo/nashorn-commonjs-modules

Он полностью реализован на Java и поддерживает загрузку модулей из других источников, кроме файловой системы (ресурсы Java, пользовательская база данных и т.д.).

Он опубликован на Maven Central, если кто-то хочет его использовать.

Ответ 5

Там также 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 был совершенно счастлив, хотя я не уверен, найдет ли он сторонний плагины или нет...