graalvm 是直接支持es6模塊的,以前有寫過基於require 模塊模式的npm包加載處理(jvm-npm)以下是我們
基於rollup 轉換comomjs 模塊為es6 模塊,方便的擴展java 的能力
場景說明
npm 包含了一個很不錯的json-mask 包,但是我們希望java可以直接集成使用,所以我們希望使用java 的graalvm js 引擎處理
集成說明
因為graalvm直接支持es6模塊,我們直接使用es6模塊就可以了,但是因為json-mask 是commonjs 模塊的,我們需要一種機制進行轉換
rollup 是一個不錯的選擇
轉換json-mask 為es6 模塊
- 項目結構
├── mymask.js
├── package.json
├── rollup.config.js
└── yarn.lock
- package.json
{
"name": "p",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@babel/preset-env": "^7.11.0",
"@babel/core": "^7.11.4",
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"rollup": "^2.26.8",
"@rollup/plugin-babel": "^5.2.0"
},
"scripts": {
"demoapp": "rollup -c rollup.config.js "
},
"dependencies": {
"json-mask": "^1.0.1"
}
}
- rollup.config.js
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
export default {
input: 'mymask.js',
output: [{
dir: 'app',
format: 'es',
plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
}],
plugins: [resolve(), commonjs()]
};
- mymask.js
const mask = require("json-mask")
module.exports = {
maskfn: function (datas, fields) {
return mask(datas, fields)
}
}
java 集成
- 項目結構
- 代碼集成
Engine engine = Engine.newBuilder().option("js.load-from-url","true").allowExperimentalOptions(true).build();
public static void es6Rollup(Engine engine) throws IOException {
Context context = Context.newBuilder().allowAllAccess(true).allowHostClassLoading(true).allowIO(true).allowNativeAccess(true).engine(engine).build();
Source mysource = Source.newBuilder("js","import mymask from \"src/main/resources/mymask.js\"\n" +
"var fields = 'url,object(content,attachments/url)';\n" +
"var originalObj = {\n" +
" id: 'z12gtjhq3qn2xxl2o224exwiqruvtda0i',\n" +
" url: 'https://plus.google.com/102817283354809142195/posts/F97fqZwJESL',\n" +
" object: {\n" +
" objectType: 'note',\n" +
" content:\n" +
" 'A picture... of a space ship... launched from earth 40 years ago.',\n" +
" attachments: [\n" +
" {\n" +
" objectType: 'image',\n" +
" url: 'http://apod.nasa.gov/apod/ap110908.html',\n" +
" image: { height: 284, width: 506 }\n" +
" }\n" +
" ]\n" +
" },\n" +
" provider: { title: 'Google+' }\n" +
"};\n" +
"\n" +
"console.log(JSON.stringify(mymask.maskfn(originalObj,fields)));","utf-8").mimeType("application/javascript+module").build();
context.eval(mysource);
}
- 運行效果
說明
一些額外的說明,nginx 的njs 也是支持js ,但是目前在js 的兼容上不是很好,有些特性是不支持的,還是有待提升的,graalvm 就很不錯了
參考資料
https://github.com/rollup/plugins/tree/master/packages/commonjs
https://github.com/graalvm/graaljs/blob/master/docs/user/JavaScriptCompatibility.md
https://www.cnblogs.com/rongfengliang/p/13582315.html
https://github.com/nemtsov/json-mask