電波ビーチ

☆(ゝω・)v

wails(v2)でテンプレートを作ってみる

昨年、デスクトップアプリを作るときにElectron x Expressな構成でやってみたんですが、nodeとブラウザもまるごと内蔵する形式でバイナリファイルを出力するため、大した内容ではないのにファイルサイズがめちゃんこデカくなってしまうのがちょっと不満でした。また、全体はTypeScriptで、フロント側はVite/Reactで書きたいけどいい感じのプロジェクト構成や設定がわからず、無理やり作ってみたものの修正すらめんどくさくてほぼお蔵入りになっておりました。

代替ツールがないかなと探してみたところ、wailsというのがよさそうです。まだほとんどいじってないけど、フロントエンド用のテンプレートを作成してみるところまでメモ代わりに残しておきます。

wails

wails.io

Goで作成するGUIアプリケーションツールです。マルチプラットフォーム対応で、フロントエンド用のテンプレートがSvelteやPreact, React, Vueなどが最初から用意されていますし、自分で作ることも可能です。ブラウザを内蔵せず、Webview2ランタイムで動く*1ため、出力されるバイナリはかなり軽量です。GoのコードからJavaScriptで利用可能なメソッドや型定義を自動で生成してくれます。しかもリアルタイムに!

今回はwails自体を深く触ることはしませんが、自分の使いやすいフロントエンド用のテンプレートの作成を試してみます。こんな感じのを作ります。

  • vite v5
  • react v18
  • typescript v5

また、本筋とは関係ないですがwailsでのnpmパッケージのインストールと実行にbunを使う想定です。ついでにbiomeも使うようなカスタマイズを施します。

2024/01/07 追記:本稿で試したwailsのバージョンは 2.7.0 です。

環境

wailsの実行にはGo(1.18以上)とnpm(Node15以上)が必要です。今回はasdfで適当に作りました。

env
CPU M1 Pro
macOS 13.5.2(Ventura)
go 1.21.5
nodejs 21.5.0
bun 1.0.20

今回作成するwailsのテンプレート名はwails-vite-react-tsとします。また、フロントエンドのViteプロジェクトのテンプレート名はtemplate_wails-vite-react-tsとします。

wails準備

wailsはGoモジュールなのでgo installでインストールします

go install github.com/wailsapp/wails/v2/cmd/wails@latest

wails doctorコマンドでwailsを使用する準備ができているか確認できます。

% wails doctor

(省略)

# Dependencies
┌────────────────────────────────────────────────────────────────┐
| Dependency                | Package Name | Status    | Version |
| Xcode command line tools  | N/A          | Installed | 2397    |
| Nodejs                    | N/A          | Installed | 21.5.0  |
| npm                       | N/A          | Installed | 10.2.4  |
| *Xcode                    | N/A          | Available |         |
| *upx                      | N/A          | Available |         |
| *nsis                     | N/A          | Available |         |
└─────────────────── * - Optional Dependency ────────────────────┘

# Diagnosis
Optional package(s) installation details: 
  - Xcode: Available at https://apps.apple.com/us/app/xcode/id497799835
  - upx : Available at https://upx.github.io/
  - nsis : More info at https://wails.io/docs/guides/windows-installer/

macだとXcode Commant Line Toolsも必要みたいですね

フロントエンドのテンプレートを用意

今回作成するテンプレートは上述のとおりVite/React/tsな環境です。まずはふつうにViteプロジェクトを作成します。テンプレートにはreact-swc-tsを使いました。

yarn create vite template_wails-vite-react-ts --template react-swc-ts

無事作成されたらいつものようにyarnコマンドで依存パッケージをインストールしたいところですが、 wailsではテンプレート作成時のロックファイルはpackage-lock.jsonを決め打ちで参照するようです。なのでここではnpm installで各種パッケージをインストールします。

biomeの初期設定

このテンプレートではLinter/formatterにbiomeを使う・ESLintを使用しないようにしてみます。viteによって生成されたデフォルトのプロジェクトからESLint関係のファイルを修正・削除します。自分の場合は.eslintrc.cjsファイルを削除し、package.jsonでESLint関係の依存やnpm scriptも削除しました。

{
  "name": "template_wails-vite-react-ts",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.43",
    "@types/react-dom": "^18.2.17",
    "@vitejs/plugin-react-swc": "^3.5.0",
    "typescript": "^5.2.2",
    "vite": "^5.0.8"
  }
}

そのあと、biomeをインストールします。同時にpackage-lock.jsonが生成されます。ついでにbiomeの設定ファイル(biome.json)も作ります。

npm install --save-dev --save-exact @biomejs/biome
npx @biomejs/biome init

biome.jsonの設定は適当にやります(本稿下部に作成したテンプレートのリポジトリのリンクがあるのでそちらを参照ください)

あとはREADME.md.gitignoreといったwailsテンプレートに不要なファイルも削除しておきました。 これでフロントエンド用のテンプレートの準備は完了です。

template_wails-vite-react-ts % tree -L  1
.
├── biome.json
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

node_modulesはテンプレート作成時に無視されるので消さなくていいです。

wailsのテンプレートを作成する

さきほど用意したフロントエンド用のテンプレートを使って、今度はwailsのテンプレートを作成します。wails generate templateコマンドを使います。この際、フロントエンド用のテンプレートはwailsプロジェクトのfrontendディレクトリ内に格納するようなオプションにしました。

% wails generate template -name wails-vite-react-ts -frontend ./template_wails-vite-react-ts

# Generating template

  • Extracting base template files...
  • Migrating existing project files to frontend directory...
  • Updating package.json data...
  • Renaming package.json -> package.tmpl.json...
  • Updating package-lock.json data...
  • Renaming package-lock.json -> package-lock.tmpl.json...
 ♥   If Wails is useful to you or your company, please consider sponsoring the project:
https://github.com/sponsors/leaanthony

これでフロントエンド用のViteプロジェクトテンプレートtemplate_wails-vite-react-tsは不要です。フォルダごと削除しました。

wailsテンプレートを修正する

生成されたwailsのテンプレートにはgo.tmp.modmain.go.tmplといったgoのテンプレート、およびfrontend/pacakge.tmpl.jsonfrontend/pacakge-lock.tmpl.jsonといったフロントエンド用のテンプレート、それとバイナリ出力用のshellスクリプトが格納されているscriptsディレクトリが含まれています。このままでもいいのですが、テンプレートとして使う練習のためここではあえて修正をいれてみます。

goのテンプレートファイル

main.go.tmplを修正してみました。デフォルトでは「出力するGUIのウインドウサイズが固定かつウインドウの移動ができない」ようになっている(macの設定。windows/linuxでは未確認)ので、これをサイズ可変・移動可能なテンプレートにしておきます。

main.go.tmpl

// ... 省略
    err := wails.Run(&options.App{
        Title:             "{{.ProjectName}}",
        Width:             1024,
        Height:            768,
        // MinWidth:          1024, コメントアウトした。以下同じ
        // MinHeight:         768,
        // MaxWidth:          1280,
        // MaxHeight:         800,
        // ... 省略
        // Mac platform specific options
        Mac: &mac.Options{
            TitleBar: &mac.TitleBar{
                TitlebarAppearsTransparent: false, // trueから修正
        // ... 省略

NEXTSTEPS.md

次はテンプレート生成時に作成されたNEXTSTEPS.mdの内容に沿って各種設定ファイルを修正します。修正用のTODOメモみたいなもんですね。

まずtemplate.jsonで、これはテンプレートとして配布するときのメタ情報ファイルだと思われます。配布する前提でなければこのままでもいいし何を書いても問題ないです。適当に修正してください。

次にREADME.mdの修正です。これも配布するとき用だけなので、自分だけで使う分にはそのままでいいしファイル自体無くてもいいです。

そしてwails自体の設定であるwails.tmpl.jsonです。デフォルトではこんな感じ

wails.tmpl.json

{
  "$schema": "https://wails.io/schemas/config.v2.json",
  "name": "{{.ProjectName}}",
  "outputfilename": "{{.BinaryName}}",
  "frontend:install": "npm install",
  "frontend:build": "npm run build",
  "author": {
    "name": "{{.AuthorName}}",
    "email": "{{.AuthorEmail}}"
  }
}

今回はviteの実行やnodeパッケージインストールはbunを使うようにするのと、Goのコードから自動生成されるJSのメソッドや型定義ファイルの生成先を指定する、みたいな設定にしました。

wails.tmpl.json
{
  "$schema": "https://wails.io/schemas/config.v2.json",
  "name": "{{.ProjectName}}",
  "outputfilename": "{{.BinaryName}}",
  "frontend:install": "bun install",
  "frontend:build": "bun run build",
  "frontend:dev:watcher": "bun run dev",
  "frontend:dev:serverUrl": "auto",
  "wailsjsdir": "./frontend/src/lib",
  "author": {
    "name": "{{.AuthorName}}",
    "email": "{{.AuthorEmail}}"
  }
}

あと、成果物が含まれてそうなpublicとかdistフォルダも消すように書いてあります。ここでは一回もビルドしてないし余計なファイルはとくにない(唯一,Viteプロジェクトからテンプレートを生成したのでfrontned/publicフォルダがあるが、viteのロゴのsvgファイルがひとつあるだけでした)ので、無視することにします。

ここまで整えたら、最後にNEXTSTEPS.md自体を削除して、wailsのテンプレート作成は終了です。

テンプレートを使ってwailsプロジェクトを始めてみる

wailsプロジェクトの開始はwails init -n <proj_name> -t <テンプレート>で始めます。このとき、IDEによってはwailsから開発時の構成設定ファイルが提供されているので、ありがたく使用することにします。

wails.io

Wailsでは、優れた開発体験の提供を目指しています。 その一環として、統合開発環境特有の構成設定の生成をサポートしており、より快適にプロジェクトをセットアップできるようになっています。

現在はVisual Studio Codeをサポートしていますが、今後、Golandなど他の統合開発環境もサポートしていく予定です。

やってみましょう。sample_1って名前のwailsプロジェクトを作成してみます。

% wails init -n sample_1 -t ./wails-vite-react-ts -ide v
scode
Wails CLI v2.7.1


# Initialising Project 'sample_1'
Project Name      | sample_1                                                        
Project Directory | /Users/username/Documents/workspace/main/wails-react-vite-ts/sample_1
Template          | wails template for react-vite-ts                                
Template Source   | https://github.com/halllllll/wails-react-vite-ts                

 INFO  VSCode config files generated.

Initialised project 'sample_1' in 292ms.

生成されたプロジェクトファイル内の.vscodeフォルダにwailsに特化したtask.jsonlaunch.jsonが作られてます。嬉しいですね

開始するにはプロジェクトのディレクトリでwails devです。Go/Reactどちらを編集しても保存したときに変更が反映されるのがわかります。Goのコードの編集だと再ビルドに数秒くらいかかりますが手動でやるよりはるかに快適です。

テンプレートを使ってwailsプロジェクトを生成する方法として、実ファイルがなくても、github経由でも構成できます。今回作成したテンプレートはこちらです。

github.com

これを使ってwailsプロジェクトを作るには、wailsの環境を整えてから

wails init -n sample -t https://github.com/halllllll/wails-react-vite-ts -ide vscode

とすればいいです。

おわりに

wailsのテンプレート作成についてのメモでした。

*1:wails v1まではElectronベースだったそうです