|
| 1 | +--- |
| 2 | +title: Node.js サイドカー |
| 3 | +sidebar: |
| 4 | + order: 1 |
| 5 | +i18nReady: true |
| 6 | +--- |
| 7 | + |
| 8 | +import CommandTabs from '@components/CommandTabs.astro'; |
| 9 | +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; |
| 10 | +import CTA from '@fragments/cta.mdx'; |
| 11 | +import TranslationNote from '@components/i18n/TranslationNote.astro'; |
| 12 | + |
| 13 | +この章では、Node.js アプリケーションを自己完結型バイナリにパッケージ化して、エンドユーザーが Node.js をインストールすることなく Tauri アプリケーションの「サイドカー」として利用できるようにします。 |
| 14 | +このチュートリアル例は、デスクトップ・オペレーティング・システムにのみ適用可能です。 |
| 15 | + |
| 16 | +「Tauri サイドカー」の仕組みをより深く理解するために、まずは一般的な [サイドカー・ガイド] を読むことをお勧めします。 |
| 17 | + |
| 18 | +以下の事例では、コマンドライン [process.argv] から入力を読み取り、[console.log] を使用して出力を stdout(標準出力)に書き込む Node.js アプリケーションを作成します。<br/> |
| 19 | +「ローカルホスト・サーバー」、「stdin/stdout」(標準入出力)、「ローカル・ソケット」などといった代替のプロセス間通信システムを活用できます。 |
| 20 | +これらはそれぞれに利点、欠点、セキュリティ上の懸念があることに注意してください。 |
| 21 | + |
| 22 | +## 事前準備(必要なもの) |
| 23 | + |
| 24 | +シェル・プラグインを使用してセットアップされた「既存の Tauri アプリケーション」。このシェル・プラグインは、ローカルでコンパイルおよび実行を行ないます。 |
| 25 | + |
| 26 | +:::tip[試作アプリの作成] |
| 27 | + |
| 28 | +あなたが上級ユーザーでない場合は、ここで提供されているオプションとフレームワークをそのまま使用することを**強く推奨**します。これはあくまで「試作(ラボ)」なので、作業終了後にはプロジェクトを削除できます。 |
| 29 | + |
| 30 | +<CTA /> |
| 31 | + |
| 32 | +- プロジェクト名: `node-sidecar-lab` |
| 33 | +- フロントエンド用言語の選択: `Typescript / Javascript` |
| 34 | +- パッケージ・マネージャーの選択: `pnpm` |
| 35 | +- UI テンプレートの選択: `Vanilla` |
| 36 | +- UI フレーバーの選択: `Typescript` |
| 37 | +- モバイル用プロジェクトも設定しますか?: `yes` |
| 38 | + |
| 39 | +::: |
| 40 | + |
| 41 | +:::note |
| 42 | +プラグインを正しく設定して初期化するには、まず[シェル・プラグイン・ガイド](/ja/plugin/shell/)に従ってください。 |
| 43 | +プラグインの初期化と設定が行なわれていないと、以下の事例は機能しません。 |
| 44 | +::: |
| 45 | + |
| 46 | +## ガイド |
| 47 | + |
| 48 | +<Steps> |
| 49 | + |
| 50 | +1. ##### サイドカー・プロジェクトの初期化 |
| 51 | + |
| 52 | + サイドカー実装を格納する新しい Node.js プロジェクトを作成しましょう。 |
| 53 | + **Tauri アプリケーションのルート・フォルダー** に新しいディレクトリを作成し(この事例では `sidecar-app` と呼びます)、そのディレクトリ内で、好みの Node.js パッケージ・マネージャーの `init` コマンドを実行します。 |
| 54 | + |
| 55 | + <CommandTabs npm="npm init" yarn="yarn init" pnpm="pnpm init" /> |
| 56 | + |
| 57 | + [pkg] コマンドを使用して、Node.js アプリケーションを自己完結型バイナリにコンパイルします。 |
| 58 | + |
| 59 | + <TranslationNote lang="ja"> |
| 60 | + |
| 61 | + **自己完結型バイナリ** 原文 a self contained binary: この語は本稿一行目にも記載あり。ただし、この「ガイド」項目内では a self contain**er** binary と記載されており、表記のゆらぎか誤記かは不明。翻訳では self contained の意味として表記を統一してあります。 |
| 62 | + |
| 63 | + </TranslationNote> |
| 64 | + |
| 65 | + それを開発依存関係としてインストールしましょう: |
| 66 | + |
| 67 | + <CommandTabs |
| 68 | + npm="npm add @yao-pkg/pkg --save-dev" |
| 69 | + yarn="yarn add @yao-pkg/pkg --dev" |
| 70 | + pnpm="pnpm add @yao-pkg/pkg --save-dev" |
| 71 | + /> |
| 72 | + |
| 73 | +1. ##### サイドカー・ロジックの記述 |
| 74 | + |
| 75 | + では、Tauri アプリケーションによって実行される JavaScript コードの作成を始めましょう。 |
| 76 | + |
| 77 | + この事例では、コマンドライン引数からコマンドを処理し、出力を stdout(標準出力)に書き出します。 |
| 78 | + つまり、このプロセスは短命で、一度に一つのコマンドのみを処理します。 |
| 79 | + もしあなたのアプリケーションが「長い存続時間」(長命のプロセス)を必要としている場合には、別の「プロセス間通信システム」の使用を検討してください。 |
| 80 | + |
| 81 | + `sidecar-app` ディレクトリに `index.js` ファイルを作成し、基本的な Node.js アプリを記述しましょう: |
| 82 | + |
| 83 | + ```js title=sidecar-app/index.js |
| 84 | + const command = process.argv[2]; |
| 85 | + |
| 86 | + switch (command) { |
| 87 | + case 'ping': |
| 88 | + const message = process.argv[3]; |
| 89 | + console.log(`pong, ${message}`); |
| 90 | + break; |
| 91 | + default: |
| 92 | + console.error(`unknown command ${command}`); |
| 93 | + process.exit(1); |
| 94 | + } |
| 95 | + ``` |
| 96 | + |
| 97 | +1. ##### サイドカーのパッケージ化 |
| 98 | + |
| 99 | + Node.js アプリケーションを自己完結型バイナリにパッケージ化するには、以下の `pkg` コマンドを実行します: |
| 100 | + |
| 101 | + <CommandTabs |
| 102 | + npm="npm run pkg -- --output app" |
| 103 | + yarn="yarn pkg --output app" |
| 104 | + pnpm="pnpm pkg --output app" |
| 105 | + /> |
| 106 | + |
| 107 | + これにより、Linux および macOS では `sidecar-app/app` バイナリが作成され、Windows では `sidecar-app/app.exe` 実行可能ファイルが作成されます。 |
| 108 | + このファイル名を Tauri サイドカー・ファイル名で要求される形式に変更するには、次の Node.js スクリプトを使用します: |
| 109 | + |
| 110 | + ```js |
| 111 | + import { execSync } from 'child_process'; |
| 112 | + import fs from 'fs'; |
| 113 | + |
| 114 | + const ext = process.platform === 'win32' ? '.exe' : ''; |
| 115 | + |
| 116 | + const rustInfo = execSync('rustc -vV'); |
| 117 | + const targetTriple = /host: (\S+)/g.exec(rustInfo)[1]; |
| 118 | + if (!targetTriple) { |
| 119 | + console.error('Failed to determine platform target triple'); |
| 120 | + } |
| 121 | + fs.renameSync( |
| 122 | + `app${ext}`, |
| 123 | + `../src-tauri/binaries/app-${targetTriple}${ext}` |
| 124 | + ); |
| 125 | + ``` |
| 126 | + |
| 127 | +1. ##### Tauriアプリケーションでのサイドカー設定 |
| 128 | + |
| 129 | + Node.js アプリケーションの準備ができたので、[`bundle > externalBin`] 配列を設定して、これを Tauri アプリケーションに接続します: |
| 130 | + |
| 131 | + ```json title="src-tauri/tauri.conf.json" |
| 132 | + { |
| 133 | + "bundle": { |
| 134 | + "externalBin": ["binaries/app"] |
| 135 | + } |
| 136 | + } |
| 137 | + ``` |
| 138 | + |
| 139 | + Tauri CLI は、サイドカー・バイナリが `src-tauri/binaries/app-<target-triple>` として存在する限り、サイドカー・バイナリのバンドルを処理します。 |
| 140 | + |
| 141 | + <TranslationNote lang="ja"> |
| 142 | + |
| 143 | + **target-triple** 「target」はアプリが対象とするプラットフォーム、「triple」は target の内容を示す三要素 \<machine>-\<vendor>-\<os>: 例 aarch64-apple-darwin(ARM64-apple-macOS)〔[参考](https://doc.rust-lang.org/nightly/rustc/platform-support.html)〕 |
| 144 | + |
| 145 | + </TranslationNote> |
| 146 | + |
| 147 | +1. ##### サイドカーの実行 |
| 148 | + |
| 149 | + サイドカー・バイナリは、Rust コードからでも、直接 JavaScript からでも実行できます。 |
| 150 | + |
| 151 | + <Tabs syncKey="lang"> |
| 152 | + |
| 153 | + <TabItem label="JavaScript"> |
| 154 | + |
| 155 | + Node.js サイドカーで `ping` コマンドを直接実行してみましょう: |
| 156 | + |
| 157 | + ```javascript |
| 158 | + import { Command } from '@tauri-apps/plugin-shell'; |
| 159 | + |
| 160 | + const message = 'Tauri'; |
| 161 | + |
| 162 | + const command = Command.sidecar('binaries/app', ['ping', message]); |
| 163 | + const output = await command.execute(); |
| 164 | + const response = output.stdout; |
| 165 | + ``` |
| 166 | + |
| 167 | + </TabItem> |
| 168 | + |
| 169 | + <TabItem label="Rust"> |
| 170 | + |
| 171 | + Tauri コマンド `pipe` を Node.js サイドカーにパイプ処理をしてみましょう: |
| 172 | + |
| 173 | + ```rust |
| 174 | + #[tauri::command] |
| 175 | + async fn ping(app: tauri::AppHandle, message: String) -> String { |
| 176 | + let sidecar_command = app |
| 177 | + .shell() |
| 178 | + .sidecar("app") |
| 179 | + .unwrap() |
| 180 | + .arg("ping") |
| 181 | + .arg(message); |
| 182 | + let output = sidecar_command.output().unwrap(); |
| 183 | + let response = String::from_utf8(output.stdout).unwrap(); |
| 184 | + response |
| 185 | + } |
| 186 | + ``` |
| 187 | + |
| 188 | + </TabItem> |
| 189 | + |
| 190 | + </Tabs> |
| 191 | + |
| 192 | +</Steps> |
| 193 | + |
| 194 | +[サイドカー・ガイド]: /ja/develop/sidecar/ |
| 195 | +[process.argv]: https://nodejs.org/docs/latest/api/process.html#processargv |
| 196 | +[console.log]: https://nodejs.org/api/console.html#consolelogdata-args |
| 197 | +[pkg]: https://github.com/vercel/pkg |
| 198 | +[`bundle > externalBin`]: /reference/config/#externalbin |
| 199 | + |
| 200 | +<div style="text-align: right"> |
| 201 | + 【※ この日本語版は、「Feb 22, 2025 英語版」に基づいています】 |
| 202 | +</div> |
0 commit comments