Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Single Executable Applicationsについて / About Single Executable Applications

Single Executable Applicationsについて / About Single Executable Applications

関西Node学園 10時限目の発表資料です。
Node.js v19.7で追加された機能 “Single Executable Applications” について説明しています。

スライド内のアプリケーション例はGitHubに公開しています

shimataro

May 09, 2023
Tweet

More Decks by shimataro

Other Decks in Programming

Transcript

  1. Single Executable
    Applicationsについて
    小田島 @shimataro999
    関西Node学園 10時限目
    https://nodejs.connpass.com/event/280838/

    View Slide

  2. 自己紹介
    さくらインターネット所属
    大体このアイコン使ってます
    小田島 太郎
    Web業界の前は手品業界にいました
    (今も副業でやってます)
    @shimataro999
    https://shimataro.me

    View Slide

  3. この発表について
    ▼内容
    Node.js v19.7で追加された機能 “Single Executable Applications”
    (以下SEA)について
    ▼対象者
    Node.jsの基本的なことは知っている
    ▼その他
    発表内容はLinuxで動作確認しています
    スライドは公開しています
    → https://speakerdeck.com/shimataro
    完全に理解した
    何も
    わからない
    チョット
    デキル
    このへん

    View Slide

  4. SEAとは?

    View Slide

  5. ChatGPTに聞いてみた
    Single Executable Applicationsとは何ですか?パリピ風に教えてください
    Single Executable Applicationsってのは、一つのプログラムファイルに複数のファイルやライブラリが詰め込まれた、超絶便利なアプリのことだよ!
    いつも複数のファイルを扱うのが面倒だったり、バージョンの問題でライブラリがうまく動かなかったりって経験がある人には、めっちゃありがたい存在だ
    ね。
    例えば、ゲームなんかは、グラフィックや音声、プログラム自体など、たくさんのファイルが必要だけど、それらをひとまとめにして、実行ファイルをダブルク
    リックするだけで遊べるようにするってわけ。
    パリピ風に言うと、「まるでパーティーで全員集合してるみたいに、アプリ内の全てのファイルがひとつになっちゃってるから、めっちゃ楽ちんで、みんなすぐ
    に使えちゃうってわけ!」って感じかな!

    View Slide

  6. よくわからなかったのでもう一回聞いてみた
    ツンデレ風だとどうなりますか?
    ほ、ほんとに知りたいの?!う、うっそうそ、私なんてSingle Executable Applicationsなんて知らないもんっ!でも、でも、た、たしかに便利なんだから、
    ちょっとだけ教えてあげるけど、嫌いだからね!
    Single Executable Applicationsってのは、ひとつのプログラムファイルに、いろんなファイルやライブラリが詰め込まれている、うざったいアプリなんだか
    らっ!いつも、このファイルはここに、あのファイルはあっちにって、めんどくさい作業がいらないのはいいけど、私は個別のファイルをいじりたい時もある
    のよ!
    でも、でも、たまには便利かもしれないわね。例えば、ゲームなんかは、グラフィックや音声、プログラム自体など、たくさんのファイルが必要だけど、それら
    をひとまとめにして、実行ファイルをダブルクリックするだけで遊べるようにするってわけ。まあ、私は使わないわよ!そんなこと、誰でもできるもん!

    View Slide

  7. よくわからなかったのでもう一回聞いてみた
    ツンデレ風だとどうなりますか?
    ほ、ほんとに知りたいの?!う、うっそうそ、私なんてSingle Executable Applicationsなんて知らないもんっ!でも、でも、た、たしかに便利なんだから、
    ちょっとだけ教えてあげるけど、嫌いだからね!
    Single Executable Applicationsってのは、ひとつのプログラムファイルに、いろんなファイルやライブラリが詰め込まれている、うざったいアプリなんだか
    らっ!いつも、このファイルはここに、あのファイルはあっちにって、めんどくさい作業がいらないのはいいけど、私は個別のファイルをいじりたい時もある
    のよ!
    でも、でも、たまには便利かもしれないわね。例えば、ゲームなんかは、グラフィックや音声、プログラム自体など、たくさんのファイルが必要だけど、それら
    をひとまとめにして、実行ファイルをダブルクリックするだけで遊べるようにするってわけ。まあ、私は使わないわよ!そんなこと、誰でもできるもん!
    従来のNode.jsランタイムでソースコードを実行するのではなく
    単独で実行可能なバイナリファイルを生成

    View Slide

  8. ちょっと補足
    https://nodejs.org/api/single-executable-applications.html
    仕組み
    ● Node.jsランタイムを、スクリプトを注入できるような構成
    にした
    ● 実行時に、注入されたスクリプトがあるかを確認
    ● あればスクリプトを実行、なければ通常の
    Node.jsとして動作
    制約
    ● 現時点では単一のCommonJSファイルのみ対応

    View Slide

  9. つまりこういうこと
    ● C言語のように、ソースコードを実行可能バイナリに変換するわけではない
    ● Node.jsのランタイムに混ぜ込むイメージ
    C言語の場合
    foo.c
    実行可能バイナリ
    変換
    SEAの場合
    foo.js
    node
    実行可能バイナリ

    View Slide

  10. とりあえず使ってみる

    View Slide

  11. JavaScriptファイルを用意
    // 地獄の言葉
    console.log("hell word");
    hell.js

    View Slide

  12. バイナリ生成手順(v19.7)
    https://nodejs.org/docs/latest-v19.x/api/single-executable-applications.html
    Node.jsランタイムを
    作業ディレクトリにコピー
    ランタイムの電子署名を削除
    (Windows / macOS)
    hell.jsをランタイムに注入
    注入したランタイムに電子署名を付加
    (Windows / macOS)

    View Slide

  13. バイナリ生成手順(v19.7)
    https://nodejs.org/docs/latest-v19.x/api/single-executable-applications.html
    Node.jsランタイムを
    作業ディレクトリにコピー
    ランタイムの電子署名を削除
    (Windows / macOS)
    hell.jsをランタイムに注入
    注入したランタイムに電子署名を付加
    (Windows / macOS)
    $ ./hell
    Segmentation fault (コアダンプ)

    View Slide

  14. バイナリ生成手順(v20.0)
    https://nodejs.org/docs/latest-v20.x/api/single-executable-applications.html
    Node.jsランタイムを
    作業ディレクトリにコピー
    ランタイムの電子署名を削除
    (Windows / macOS)
    hell.jsを
    注入用のブロブに変換
    ブロブをランタイムに注入
    注入したランタイムに電子署名を付加
    (Windows / macOS)

    View Slide

  15. バイナリ生成手順(v20.0)
    https://nodejs.org/docs/latest-v20.x/api/single-executable-applications.html
    Node.jsランタイムを
    作業ディレクトリにコピー
    ランタイムの電子署名を削除
    (Windows / macOS)
    hell.jsを
    注入用のブロブに変換
    ブロブをランタイムに注入
    注入したランタイムに電子署名を付加
    (Windows / macOS)
    $ ./hell
    hell word
    (node:66827) ExperimentalWarning: Single executable application is
    an experimental feature and might change at any time
    (Use `hell --trace-warnings ...` to show where the warning was
    created)
    地獄の言葉が表示された!!

    View Slide

  16. ちょっとだけ複雑なものを
    作ってみる

    View Slide

  17. ちょっとだけ複雑なものを作ってみる
    現実の開発で必要なもの
    ● 複数ファイルに分割
    ● サードパーティーモジュール(
    NPMパッケージ)
    ● AltJS

    View Slide

  18. ちょっとだけ複雑なものを作ってみる
    https://github.com/shimataro/sea-example
    ● Fastifyを使ったウェブアプリケーション
    ● TypeScriptで記述
    ● 複数ファイル(2ファイル)で構成
    ● 動作理解が目的なので、最低限の構成のみ
    npm run buildでビルド
    ● build: @vercel/nccでトランスパイル&バンドル
    ● postbuild: ブロブ生成&実行バイナリ生成

    View Slide

  19. 実行結果
    $ ./sea-example
    (node:82154) ExperimentalWarning: Single executable application is an
    experimental feature and might change at any time
    (Use `sea-example --trace-warnings ...` to show where the warning was
    created)
    $ curl http://localhost:3000
    {"hell":"word"}
    サーバ側
    クライアント側
    地獄の言葉が返ってきた!!

    View Slide

  20. 実行結果
    $ ./sea-example
    (node:82154) ExperimentalWarning: Single executable application is an
    experimental feature and might change at any time
    (Use `sea-example --trace-warnings ...` to show where the warning was
    created)
    $ curl http://localhost:3000
    {"hell":"word"}
    サーバ側
    クライアント側
    地獄の言葉が返ってきた!!
    本当に単一ファイル?
    ● バイナリだけを他のマシンに移動 しても実行できた
    ● ≒他の依存ファイルはなさそう

    View Slide

  21. 結局どうなん?

    View Slide

  22. 使いどころ
    コマンドラインツール
    ● 多分あんまり実用的ではない
    ● ちょっとしたツールを作るたびにバカでかいランタイムが必要
    ● package.jsonのbinフィールドを使う or Cとかで作成するほうがいい
    ウェブアプリケーション
    ● 多分これが実用的な用途(
    Node.jsチームもこれを想定?)
    ● システムに影響を与えずに
    ランタイムバージョンを気軽に更新できる
    ● なにか問題があればすぐに戻せる
    ● 自動デプロイにも組み込めそう

    View Slide

  23. 注意点
    Graceful Reload
    ● 業務システムは、極力無停止でリリースしたい
    ● SEAでは、PM2等のNode.js用プロセスマネージャーを使えない

    View Slide

  24. 注意点
    Graceful Reload
    ● 業務システムは、極力無停止でリリースしたい
    ● SEAでは、PM2等のNode.js用プロセスマネージャーを使えない
    対応方法
    ● Circusなどの汎用プロセスマネージャー
    を使う
    ● K8sとかNomadとかでコンテナ管理する

    View Slide

  25. 注意点
    Graceful Reload
    ● 業務システムは、極力無停止でリリースしたい
    ● SEAでは、PM2等のNode.js用プロセスマネージャーを使えない
    対応方法
    ● Circusなどの汎用プロセスマネージャー
    を使う
    ● K8sとかNomadとかでコンテナ管理する
    ただし...
    ● コンテナ管理するなら、SEAを使わなくても気軽にランタイムバージョンを更新できる
    ● =SEAのメリットが薄れる

    View Slide

  26. まとめ

    View Slide

  27. まとめ
    v19.7で、実行可能バイナリを生成する機能が追加された

    View Slide

  28. まとめ
    v19.7で、実行可能バイナリを生成する機能が追加された
    ソースコードを実行バイナリに変換するというよりは
    Node.jsのランタイムにソースコードをくっつける
    イメージ

    View Slide

  29. まとめ
    v19.7で、実行可能バイナリを生成する機能が追加された
    ソースコードを実行バイナリに変換するというよりは
    Node.jsのランタイムにソースコードをくっつける
    イメージ
    ウェブアプリケーションで使えば
    気軽にランタイムバージョンを変更
    できそう

    View Slide

  30. まとめ
    v19.7で、実行可能バイナリを生成する機能が追加された
    ソースコードを実行バイナリに変換するというよりは
    Node.jsのランタイムにソースコードをくっつける
    イメージ
    ウェブアプリケーションで使えば
    気軽にランタイムバージョンを変更
    できそう
    無停止リリースしたい場合はひと工夫必要

    View Slide

  31. まとめ
    v19.7で、実行可能バイナリを生成する機能が追加された
    ソースコードを実行バイナリに変換するというよりは
    Node.jsのランタイムにソースコードをくっつける
    イメージ
    ウェブアプリケーションで使えば
    気軽にランタイムバージョンを変更
    できそう
    無停止リリースしたい場合はひと工夫必要
    v19.7のSegmentation faultは忘れてください

    View Slide

  32. View Slide