nodeのSEAでexeファイルを生成してみた

に公開

はじめに

.exeに代表される実行ファイルへの変換方法を調べると、様々なパッケージが見つかる。
しかしサポートの終了しているものも多い。
そこで今回は node v21 から実験的に実装された Single Executable Appliction (SEA) を用いてexeファイルの生成を行うこととした。
今回の筆者の環境はざっくり以下の通り。

  • Windows 11
  • node v22
  • Git Bash

公式リファレンス: https://nodejs.org/api/single-executable-applications.html

手順

CJSファイルを用意する

今回筆者が作業したのは、ファイルの変換を行うnodeアプリ
https://github.com/Asapi1020/spawn-cycle-defs-converter
まずビルドして

node dist/index.js

のように実行できるJSを出力した
ESMのプロジェクトだが、SEAはv22でCJSにしか対応していないので

import("./dist/index.js")

とだけ書かれたindex.cjsを用意した

cjsからblobを生成する

まずSEAの設定ファイルを用意する

{
    "main": "./index.cjs",
    "output": "./blob/index.blob",
    "disableExperimentalSEAWarning": true
}

入力のCJSと出力のBLOB指定は必須。
disableExperimentalSEAWarningはデフォルトでfalseだが、成果物のexeを実行した際に警告が表示される。
警告を非表示にしたければ設定しよう。
設定ファイルを用意したら次を実行

node --experimental-sea-config your-config.json

nodeのexeを作る

node -e "require('fs').copyFileSync(process.execPath, 'your-app.exe')"

これでexeファイルが出力される。
まだこれは実行してもnodeが立ち上がるだけである。

blobをexeにinjectする

npx postject your-app.exe NODE_SEA_BLOB your-blob.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2

これを実行するとexe実行時にnodeアプリと同じ機能が働く。
おわり。

参考文献

https://deep.tacoskingdom.com/blog/250#part-h3-1-h2-0

附録

今までnode v20を使っていたのでversionを上げた。
初めてインストールした時にインストーラを用いたので、version変更をどうしようかと思索した。
fnmの導入が公式推奨だったので、これを使うことにした。
既存のnodeをWindows設定のアプリ一覧からアンインストールしnode -vで既存versionが消えたことをチェックする。
しかし、公式通りにwingetでfnmをインストールしたら上手くいかなかった。
具体的には、Git Bashとの相性が悪く、パスを通すのが恐ろしくめんどくさかった。
普段からPowershellとwingetを使っている人は困らないかもしれない。
目的である簡単なnode version管理が達成できなさそうだったので、次の方法に変えた。

curl -fsSL https://fnm.vercel.app/install | bash

Git Bash環境ですぐにfnmへのパスも通った。

fnm install 22

これでv22をinstallすると、

node -v

でnode22がインストールされていることを確認できた。

Discussion