JXCoreを使ってJavaScriptのコードをネイティブコードにパッケージ化する
JXCoreというNode.js派生プロジェクトを使い、JavaScriptのコードをネイティブコードとしてのパッケージングするのにつかってみました。
JSで作ったちょいスクリプトの配布とかで便利かもしれません。
JXCoreとは
Node.jsからフォークしたプロジェクトとしてはio.jsが有名ですが、これもNode.jsからフォークしたものの一つ。
以下のような特徴があります。
- Node.jsとの100%の互換性。Node.jsに独自機能を追加。
- マルチスレッド動作対応
- プロジェクト全体をパッケージとして一つのファイルにまとめる事が可能
- ネイティブコードとしてのパッケージングも可能
- JavScriptエンジンの切り替え可能
- V8だけではなく、SpiderMonkeyもサポート
- モバイルへの対応
- パッケージマネージャが本体に統合されている
いろいろな機能がありますが、今回はネイティブコードとしてのパッケージングだけ使ってみたいと思います。
ダウンロード
以下のページからダウンロードできます。
インストーラも、各プラットフォームごとのバイナリもあります。
Downloads | JXcore
今回は直接バイナリを使ってみます。
「Windows ia32 (V8)」をダウンロードしました。
使ってみる
ネイティブコードとしてパッケージングしてみる
続いて、本題のjsコードのネイティブ化をしてみたいと思います。
といっても、やることは少しだけ。
JXコマンドを、packageオプションをつけて実行します。ネイティブコードとしてパッケージングする場合は、nativeオプションも追加で以下のように呼び出します。
jx package [スクリプトのエントリポイント] [出力するファイル名] -native
これだけで、単一のバイナリで実行できる形にパッケージングしてくれます。
nodeのプロジェクトに、パッケージング用のタスクを追加する
Nodeからこっちに乗り換える、というのは抵抗があります。
ですが、JXCoreはNode.jsとの互換性があるので、Node.js用に作ったプロジェクトに、JXCoreを使ったパッケージング用のタスクを追加して使う、というのもアリかもしれません。
ということで、package.jsonを使って、JXCoreでネイティブ化するためのタスクを追加してみたいと思います。
サンプルとして、ただのHelloWorldなプロジェクトに追加してみます。
プロジェクト構成
こんな感じのプロジェクト構成です。
binフォルダ以下に、JXCoreのバイナリを置いておきます。
app.js
本体のコードはconsole出力だけ。
console.log('Hello world');
package.json
{ "name": "JxcoreTest", "version": "0.0.0", "description": "JxcoreTest", "main": "app.js", "scripts": { "start": "node app.js", "startJx": "bin\\jx_win32v8\\jx app.js", "pack": "bin\\jx_win32v8\\jx package app.js JxcoreTest -native" } }
以下のコマンドで、package.jsonに定義したネイティブ化するためのタスクを実行します。
npm run pack
こういうexeファイルが出来上がります。
普通に実行できるexeとなりました。
(コンソールの出力結果が見えるように、コマンドプロンプトから実行してます。)
もうちょい複雑なケース
npmで取得した、依存するライブラリがあるような場合でも、依存関係まで含めてパッケージングすることができます。
express-generatorで生成したプロジェクトでも、依存しているライブラリまで含めて、単一のバイナリに出来ました。
プロジェクト全体
ちなみに、express-generatorではエントリポイントはbin/wwwというファイルになります。
ですが.js以外の拡張子のファイルを、「jx package」のコマンドに渡すと以下のようなエラーで止まってしまいます。
ということで、エントリポイントのファイルはwww.jsという名前にリネームしてます。
package.json
{ "name": "ExpressTest", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www.js", "startJx": "bin\\jx_win32v8\\jx bin\\www.js", "pack": "bin\\jx_win32v8\\jx package bin\\www.js ExpressTest -native" }, "dependencies": { "body-parser": "~1.12.0", "cookie-parser": "~1.3.4", "debug": "~2.1.1", "ejs": "~2.3.1", "express": "~4.12.2", "morgan": "~1.5.1", "serve-favicon": "~2.2.0" } }
出来上がったexeをダブルクリックでサーバーが起動します。