Motoko Dev Server の発表:Web3 Dapp のライブ・リローディング(日本語訳)
DFINITY 公式の記事 Announcing the Motoko Dev Server: live-reloading for Web3 dapps (2023/6/28) - Ryan Vandersmith の日本語訳です。
Internet Computer ブロックチェーン上で Motoko のサービスを素早く構築し、テストするための柔軟な ライブ リロード サーバ mo-dev をご紹介します。
背景
ライブリローディング(より具体的には、ホットモジュールリプレイスメント)は、ウェブ開発者の生産性を大幅に向上させる技術として知られています。その仕組みについては、このブログ記事をチェックすることを強くお勧めします。
これは、従来の Web 開発の世界では解決済みの問題です。Vite、Next.js、Webpack dev server のような堅牢なソリューションにより、フロントエンドのコードを1行変更するだけで、通常はページをリフレッシュすることなく、ブラウザですぐに結果を確認できます。
しかし、ブロックチェーン上で動作する分散型アプリケーション(または “Dapp”)を開発する場合、この機能はほとんど存在しません。Solidity スマートコントラクト用の ZepKit など、いくつかのオプションは存在しますが、Web3 ライブリローディングの現状は、Web2 からの期待が非常に高いことを考えると、大いに不満が残ります。
そこで、Motoko プログラミング言語 の出番です。素早いコンパイル時間、モジュールベースのインポート、stable variable セマンティクスを持つ Motoko は、ゲームチェンジするライブリロードワークフローの理想的な候補です。
過去6ヶ月間、DFINITY Foundation は内部の Motoko プロジェクトにフルスタックのライブリローディングを採用し、開発時間を大幅に節約し、Internet Computer の Dapp のエンドユーザー体験を向上させるために様々なアイデアを素早く試すことができるようになりました。
これは、Motoko Dapp とスマートコントラクトのライブリロードワークフローを容易にするコマンドラインツールである Motoko Dev Server(略してmo-dev
)を使うことで可能になりました。
特徴
mo-dev
はすでに、Motoko Playground、Developer Experience Feedback Board、さらには言語独自のbase libraryなど、幅広いプロジェクトで利用されています。
それぞれのユースケースで必要とされるライブリロード機能は異なるため、私たちはプロジェクトに応じて選択できるスイスアーミーナイフのような機能を作ることにしました:
- ローカルのレプリカへのキャニスターのデプロイ
- 言語バインディングを生成
- ユニットテスト(
.test.mo
で終わるファイル)の実行 - コマンドの実行
- 上記の任意の組み合わせ
機能の完全なリストについては、プロジェクトの GitHub リポジトリをチェックしてください:
mo-dev
を使いたい理由はお分かりいただけたでしょう。ここで、いくつかの方法を紹介します:
オンラインデモ
ダウンロードせずにmo-dev
を試してみたい方は、ブラウザ上で実行できるオンラインサンプルプロジェクトをどうぞ:
インストール
ターミナルで以下のコマンドを実行してください(Node.js ≥ 16 が必要):
npm install -g mo-dev
あるいは、プロジェクトの GitHubリリース からスタンドアロンバイナリをダウンロードできます。
ツールをインストールしたら、mo-dev --help
を実行して、使用例や各機能の説明を見ることができます。
Candid UI
Candid UI を使って Motoko スマートコントラクトを開発しているとしましょう。ファイル変更時にキャニスターを再デプロイするコマンドを以下に示します:
mo-dev --deploy -y
-y
フラグは、キャニスターインターフェイスのアップグレードに関する dfx からのプロンプトに自動的に “yes” と応答します(キャニスターデータをクリアする可能性があります)。使用するケースに応じて、このフラグを付けるか付けないかは自由です。
フルスタック Dapp
mo-dev
は、Vite や Create React App のような一般的なフロントエンドビルドツールとうまく連携するように特別に設計されています。
新しいプロジェクトを始めたいのであれば、Vite + React + Motokoテンプレート(または、さらにシンプルな plain JavaScript version)の使用を検討してください。
それ以外では、バックエンドのMotoko キャニスターをライブリロードするための良い出発点は下記です:
mo-dev --generate --deploy -y
--generate
フラグは、Motoko ソースコードに変更を加えるたびに、JavaScript 言語バインディングを自動的に作成し、更新します。
この機能を単独で使うことも可能です(mo-dev --generate
)。
高度な使い方
既存の Web アプリケーションに Motoko Dev Server をプラグインしたい方のために、DFINITY で採用しているスケーラブルな Vite プロジェクト構成をご紹介します:
- プロジェクトのルートディレクトリで
npm install -D npm-run-all mo-dev
を実行する。 vite
を実行するfrontend
npm スクリプトを追加する。- 関連するフラグを付けて
mo-dev
を実行するbackend
npm スクリプトを追加する。 start
npm スクリプトをrun-p frontend backend
に変更する。
このプロジェクト設定では、npm start
が Vite と Motoko の dev サーバーを、シームレスに統合されたコンソール出力で実行します。npm run frontend
と npm run backend
を使って、別々のターミナルで出力を分けることができます。
この構成のもう一つの利点は、mo-dev
コマンドをグローバルにインストールしなくても、誰でも開発サーバーを実行できることです。
このプロジェクト設定は、dfx new コマンドの今後の変更にデフォルトで含まれることになるでしょう。
ユニットテスト
mo-dev
には、motoko-matchers のようなサードパーティライブラリと互換性のあるテストランナーが同梱されています。
ユニットテストを登録するには、プロジェクトの任意の場所に拡張子 *.test.mo
のファイルを作成します。例えば、2vxsx-fae
が anonymous principal であることを assert する基本的なユニットテストは下記です:
*.test.mo
ファイルを作成したら、以下のコマンドを実行してください:
mo-dev --test
これにより、Motoko のソースファイルを変更するたびに、すべてのユニットテストが実行されます。
--test
を--deploy
と共に使用する場合、開発サーバはキャニスターを再デプロイする前に、関連するテストがすべて成功するまで待機することに注意してください。
ライブリロード機能を使わずにテストを実行したい場合は、mo-dev
と一緒に自動的にインストールされるmo-test
コマンドを使うことができます:
mo-test --help
特定のテストファイルをフィルタリングするために、-f
フラグを付けることもできます:
mo-test -f Foo # Run test files starting with "Foo"
mo-test -f Foo.test.mo # Only run test files named "Foo.test.mo"
mo-test -f Foo -f Bar # Run test files starting with "Foo" or "Bar"
デフォルトでは、テストランナーは Motoko インタプリターを使用します。パフォーマンスが重要な場合は、Wasmtime をインストールし、test コマンドに --testmode wasi
を追加することで、コンパイルされた WASI ランタイムに切り替えることができます。
Motoko VS Code extension には、テストランナー用の UI も含まれています:
継続的インテグレーション
Motoko Dev Server は、GitHub Actions、 Travis、CircleCI などの CI 環境で使用できます。これらの環境では、mo-dev
はファイルの変更を待つ代わりに自動的に終了します。
以下のように、環境変数CI
をtrue
または1
に設定することで、ローカルシステムでも同じ効果が得られます:
CI=true mo-dev --generate --deploy
最後の考察
以下は、mo-dev
で作業する際に役に立つかもしれない、いくつかの雑学です:
- ライブリロードは Git のブランチを切り替えたときにも機能するので、コードレビューやペアプログラミングのときに覚えておくと便利です。
- dfx generateを使ったことがある人なら、
dfx generate
とdfx deploy
の両方を先に実行する必要があるという、よくある問題に遭遇したことがあるかもしれません。mo-dev --generate --deploy
は、この状況を自動的に処理してくれます。 - カスタムなライブリロードロジックは、
mo-dev --exec <command>
を使って定義できます。
フィードバックは大歓迎です!バグを見つけたり、新しい機能が欲しい場合は、お気軽に GitHubで ご連絡ください(プロジェクトをサポートするために⭐️をつけることもできます):
そうでなければ、mo-dev で構築された Developer Experience Feedback Board にリクエストを投稿してください!興味のある方はソースコードをどうぞ:
読んでくれてありがとう。乾杯!
~ Ryan