はじめに
Javascript(Node.js)は非常に便利なモジュールが揃っているのでちょっとしたツール作りに重宝していますが、Node.jsをインストールしていないユーザに配布するなら、実行ファイル形式に変換できたら便利だよなーということで、Javascript→実行ファイル変換の機能を持つ以下のアプリを試してみました。
パッケージ化例
以下のコードをパッケージ化してみました
test.js
console.log('Hello world');
console.log(process.argv);
console.log(process.versions);
Windows10 64bitのcmd.exe上で、以下のコマンドでパッケージ化しています。
jxcore
jx package test.js -native -name output/jxcoreteest
nexe
nexe -i test.js -o output\nexetest.exe
EncloseJS
enclose -o output\enclosetest.exe test.js
パッケージ化したファイルの実行結果
JXcore
Hello world
[ 'd:\\user\\js\\packaging-test\\src\\output\\jxcoreteest.exe' ]
{ http_parser: '1.0',
node: '0.10.40',
jxcore: '0.3.1.1',
ch: 0,
v8: '3.14.5.9',
sm: 0,
embedded: { sqlite: '3.9.1' },
ares: '1.9.0-DEV',
uv: '0.10.36',
zlib: '1.2.3',
modules: '11',
openssl: '1.0.1p' }
nexe
Hello world
[ 'd:\\user\\js\\packaging-test\\output\\nexetest.exe',
'nexe.js' ]
{ http_parser: '2.8.0',
node: '8.11.1',
v8: '6.2.414.50',
uv: '1.19.1',
zlib: '1.2.11',
ares: '1.10.1-DEV',
modules: '57',
nghttp2: '1.25.0',
openssl: '1.0.2o',
icu: '60.1',
unicode: '10.0',
cldr: '32.0',
tz: '2017c' }
EncloseJS
*** Evaluation version. Please subscribe to full version.
Hello world
[ 'd:\\user\\js\\packaging-test\\output\\enclosetest.exe',
'd:\\user\\js\\packaging-test\\output\\enclosetest.exe' ]
{ http_parser: '2.7.0',
node: '6.3.1',
v8: '5.0.71.57',
uv: '1.9.1',
zlib: '1.2.8',
ares: '1.10.1-DEV',
icu: '57.1',
modules: '48',
openssl: '1.0.2h',
enclose: '2.2.0' }
また、npm install
でインストールした外部モジュールを使用したコードも、node_modulesディレクトリごとパッケージ化してくれるので、配布の際は実行ファイル1個だけになり非常に楽です。
JXcore
長所
- パッケージ化が速い
短所
- 内包しているエンジンがNode.js Ver0.1x相当なのでES6の文法が使用できない
- ネイティブモジュール使用不可
- パッケージ化の有無で
process.argv
の内容が違う
jx test.js 1 2 3
のprocess.argv
パッケージ化前
[ 'jx',
'd:\\user\\js\\packaging-test\\src\\test.js',
'1',
'2',
'3' ]
パッケージ化後に実行ファイル名 1 2 3
を実行したときのprocess.argv
パッケージ化後
[ 'd:\\user\\js\\packaging-test\\src\\output\\jxcoreteest.exe',
'1',
'2',
'3' ]
パッケージ化したかどうかはprocess.isPackaged
で判別できるので、以下のようなコードを書く必要があります。
if (!process.isPackaged) {
process.argv.shift();
}
- 開発終了している
nexe
長所
- 内包するNode.jsのバージョンを任意に選択できる
- 当然ES6の文法使用可
短所
- ネイティブモジュール、動的require使用不可
動的requireは以下のようなコード
const moduleName = 'somemodule';
const module = require(moduleName);
インストールが非常に手間nexe本体以外にnode.jsをコンパイルできる環境(VisualStudio 2010以上(+.NET Framework4.6), Python2.x)が必要- nexe Ver2.0になって、パッケージ化の際にコンパイル済みバイナリをダウンロードするようになりました。そのためいちいちnode.jsをビルドする必要はありません
パッケージ化にべらぼうに時間がかかる初回パッケージ化時にNode.jsのダウンロード+ビルドを行うため、非常に時間がかかります。パッケージ化例のコードのパッケージ化にはi7-4790環境で15分くらいかかりました- バイナリのダウンロードを行う初回パッケージ化時は少し時間がかかりますが、2回目以降はあっという間にパッケージ化が終わります
- 以前はパッケージ化時にソースコード中のマルチバイト文字が全て削除されるという問題がありましたが、直ってました
EncloseJs
長所
- パッケージ化が速い
- 内包するNode.jsのバージョンを選択できる(0.12.x, 4.x or 6.x.) なのでこれもES6の文法使用可
- 使用できるバージョンは binaries.jsonにあります。
- ネイティブモジュール使用可、らしい
- ただしネイティブモジュールは実行ファイルにパッケージングはされず、パッケージ化した実行ファイルと一緒に配布する必要があるらしい(未確認)。
短所
- プロキシ下の環境でインストールできない
- 素の
https.get()
を使用してバイナリをダウンロードしようとしているため、プロキシ下だとインストールに失敗する。postinstall.jsを修正すればインストール可能。 - パッケージ化したファイルを実行すると、カスペルスキーが「これはAdwareだよ」警告を出す
- パッケージ化したファイルを実行すると必ず「これは評価版だから登録してね」メッセージが表示されるが、「登録」する方法が見当たらない。公式サイトの"BUY"ページは"Not available"になっているし。
まとめ(2018/5/15更新)
- パッケージ化にちょっと時間はかかるが、機能的にはnexe1択。他のツールを使う必要はなさそう
- Node.js 0.1xの文法のみを使用して書くのであればJXcoreは安定している
- カスペルスキーの警告や「登録しろ」メッセージが出るEncloseJSはちょっと不安
こんな印象です。
他にもJavascriptをコマンドラインアプリ化できるよいツールをご存じでしたら、ぜひご教示くださいませ。