0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wails を始めてみた

Last updated at Posted at 2025-01-03

はじめに

Windows のデスクトップアプリを作るのに自分は、以前は Delphi を使っていて、仕事は WinForms+VB.NET を使っていて、趣味は Electron も使っています。新たにアプリを作り始めるのに、別の開発手段も試してみようと思いました。

Wails とは

Wails は、Go 言語とウェブ技術を使用して、デスクトップアプリの構築を可能にします。「Go の力によって、Electron が軽量かつ高速になったようなもの」と考えるとよいでしょう。
イントロダクション | Wails

アプリ全体のうち Go の部分は、アプリのコードとランタイムライブラリで構成されています。 フロントエンドは webkit ウィンドウであり、フロンドエンドアセットをウィンドウ上に表示します。Go のメソッドはフロントエンドにバインドされ、ローカルの JavaScript メソッドであるかのようにフロントエンドから呼び出すことができます。
どうやって動いているの? | Wails

いわゆる「OS のネイティブアプリ」は、OS 上で実行できるバイナリファイルで、OS の機能を呼出して動作します。開発環境や開発言語が OS ごとに用意され、その OS 用の実行ファイルが作成されます。同じソースコードのプログラムを異なる OS で動作できません。
これに対して、いわゆる「ウェブアプリ」は、HTML と JavaScript で書かれたプログラムが、ウェブブラウザに読込され実行されます。同じ動作するブラウザがあれば同じウェブアプリのプログラムが異なる OS で動作します。ウェブブラウザが呼出できない OS の機能は利用できません。
「Electron」を使ったアプリは、ウェブアプリ+ウェブブラウザが実行ファイルになってネイティブアプリのように OS 上で動作します。さらに Node.js アプリを内包できて、ウェブブラウザで呼出できない OS の機能も呼出できるようになっています。ウェブブラウザおよび Node.js エンジンを OS ごとに切替して実行ファイルを作成することで、同じ HTML+JavaScript のプログラムで異なる OS で動作するアプリを作成できます。ウェブブラウザおよび Node.js エンジンを内包するため、OS ネイティブアプリに比べて実行ファイルが大きくなってしまいます。
「Tauri」アプリは、Electron の Node.js アプリの部分が、Rust アプリになっています。また Electron アプリはブラウザ機能を内容しているのに対して、OS が持つブラウザ機能を呼出します。このため、Electron アプリに比べて実行ファイルが小さくなります。
「Wails」アプリは、Tauri の Rust アプリの部分が、Go アプリになっています。

説明.png

Wails を始めてみた

  • Wails 2.9

開発および実行できる環境

Wails は、以下の環境で開発できて、作成したアプリが実行できます。

  • Windows 10 および 11 (x64 および ARM64)
  • MacOS 10.13 以降 (x64) 、MacOS 11.0 以降 (ARM64)
  • Linux (x64 および ARM64)

開発環境を準備する

以下の手順で開発環境を準備します。

インストール | Wails

Go 環境をインストールする

まず Go 環境をインストールします。

Download and install - The Go Programming Language

npm をインストールする

続いて npm をインストールします。

Node.js — Download Node.js®

WebView2 ランタイムをインストールする(Windows 環境の場合)

Windows 11 は WebView2 ランタイムを標準で持っています。そうでなければ Windows 環境に WebView2 ランタイムをインストールします。

Microsoft Edge WebView2 | Microsoft Edge Developer

xcode コマンドラインツールをインストールする(macOS 環境の場合)

macOS 環境に xcode コマンドラインツールをインストールします。

XcodeのCommand Line Toolsのみインストールする #Mac - Qiita

プロジェクトを新規作成する

プロジェクトを作成したいフォルダに移動してコマンドを実行します。

wails init -n アプリ名 -t フレームワーク名

アプリ名で指定された名前のフォルダが作成されてソースコード一式がセットされます。

プロジェクトの開始 | Wails

例えば

wails init -n HelloWails -t vanilla

新規プロジェクトの内容を確認する

アプリのベースになるプロジェクトは簡単に作成できましたが、ファイルが幾つもあります。どのファイルを変更すればいいのか。それを知るために、プロジェクトに含まれるファイルを調べてみました。

どうやって動いているの? | Wails

main.go

エントリポイントは、main.go にあります。

main.go
package main

(中略)

func main() {
	// Create an instance of the app structure
	app := NewApp()

	// Create application with options
	err := wails.Run(&options.App{
		Title: "HelloWails",
(中略)
		OnStartup: app.startup,
		Bind: []interface{}{
			app,
		},
	})

	if err != nil {
		println("Error:", err.Error())
	}

アプリが起動するときの状態を指定できそうです。

app.go

同じパッケージ mainmain.go と別に app.go に分けて記述されています。

app.go
package main

(中略)

// App struct
type App struct {
	ctx context.Context
}

// NewApp creates a new App application struct
func NewApp() *App {
	return &App{}
}

// startup is called when the app starts. The context is saved // so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx
}

ここまでは手を入れる余地なさそうです。main.go に記述してあっていいように思いました。

app.go
(前略)

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, It's show time!", name)
}

ここからアプリの独自のコードのようです。↑

frontend/wailsjs/go/main/App.js

上記の app.go のコードがフロントエンドのプログラムで使用できるよう設定されます。

App.js
export function Greet(arg1) {
  return window['go']['main']['App']['Greet'](arg1);
}
App.d.ts
export function Greet(arg1:string):Promise<string>;

この設定は wails generate module すると app.go の内容を読んで自動で作成されます。

frontend/index.html

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
    <title>HelloWails</title>
</head>
<body>
<div id="app"></div>
<script src="./src/main.js" type="module"></script>
</body>
</html>

フレームワーク Vanilla JS を指定しましたが、HTML ファイルは ID appdiv タグだけ用意するスタイルになっています。他のフレームワークを指定しても同じ内容でした。

frontend/src/main.js

main.js
import {Greet} from '../wailsjs/go/main/App';

(中略)

    // Call App.Greet(name)
    try {
        Greet(name)
            .then((result) => {
                // Update result with data back from App.Greet()
                resultElement.innerText = result;
            })
            .catch((err) => {
                console.error(err);
            });
    } catch (err) {
        console.error(err);
    }
};

上記の app.go のコードがフロントエンドのプログラムで使用できています。↑

アプリのアイコンを変更する

アプリのアイコンを変更できます。

Wailsでアプリをビルドするときにアイコンを変更する方法 - at backyard

アプリを開発モードで起動する

プロジェクトのフォルダに移動してコマンドを実行します。

wails dev

開発モードの実行ファイルが作成されて起動します。

アプリの開発 | Wails

アプリをビルド(コンパイル)する

プロジェクトのフォルダに移動してコマンドを実行します。

wails build

配布するための実行ファイルが、プロジェクトのフォルダ内の build/bin に作成されます。

プロジェクトのコンパイル | Wails

VS Code で開発する

上記のコードをエディタで編集してコマンド実行すればアプリが作成できますが、コードの編集やデバッグは IDE(統合開発環境)を使いたいものです。

VS Code (Visual Studio Code) を使うことにします。

VS Code をインストールする

VS Code をダウンロードしてインストールします。

Download Visual Studio Code - Mac, Linux, Windows

拡張機能をインストールする

Go アプリをデバッグするための拡張機能をインストールします。

Visual Studio Code for Go 開発のインストールと構成 - Go on Azure | Microsoft Learn

プロジェクトのフォルダを開く

作成したプロジェクトのフォルダを VS Code で開きます。

VSCodeの基本~プロジェクトフォルダの設定方法について解説します! | プログラミング入門ナビ by Proglus(プログラス)

launch.json を用意する①

効率よくデバッグできるように VS Code のデバッグ構成 launch.json を用意します。

公式サイトで紹介されているものを使ってみます。統合開発環境 | Wails

launch.json
{
  version: "0.2.0",
  configurations: [
    {
      "name": "Debug ●●●●",
      "type": "go",
      "request": "launch",
      "mode": "exec",
      "program": "build/bin/●●.exe",
      "cwd": "${workspaceFolder}",
      "preLaunchTask": "build",
      "env": {}
    }
  ]
}
tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "type": "shell",
      "command": "go",
      "args": [
        "build",
        "-tags", "dev",
        "-gcflags", "all=-N -l", "-o",
        "build/bin/●●.exe"
      ]
      "options": {
        "cwd": "${workspaceFolder}"
      },
    }
  ]
}

●●.exe は実際のプロジェクトに合わせて変更します。macOS の場合は ●●.app になります。↑

この設定の準備して デバッグ実行 します。

説明①.png

バックエンドの Go のプログラムは、ステップ実行したり変数ウォッチできます。フロントエンドの JavaScript のプログラムは、だめでした。

launch.json を用意する②

フロントエンドの JavaScript のプログラムにアタッチしてデバッグできないものでしょうか。

説明②.png

Wails アプリのフロントエンドは WebView を使っています。これにデバッガがアタッチできないか調べていくと、以下の記事を見つけました。

Visual Studio Code を使用して WebView2 アプリをデバッグする - Microsoft Edge Developer documentation | Microsoft Learn

launch.json
(前略)
  configurations: [
    {
      "name": "Debug ●● frontend",
      "type": "msedge",
      "request": "launch",
      "runtimeExecutable": "build/bin/●●.exe",
      "env": {
        "Path": "%path%;build/bin/;"
      },
      "useWebView": true,
      "port": 9222, // The port value is optional, and the default value is 9222.
      "url": "file:///${workspaceFolder}/frontend/index.html",
      "webRoot": "${workspaceFolder}/frontend"
    }
(後略)

上記①と併せて、バックエンドとフロントエンドのどちらもデバッグ実行できるようになると思ったのですが、

・Windows 環境しか設定できない
・VS Code の設定だけでなく Windows でレジストリを変更しないといけない

なので、使うのは断念しました。

launch.json を用意する③

wails dev して開発モードで起動すると、ブラウザからアプリを操作できるようにするウェブサーバを起動する。これにより任意のブラウザ拡張機能を利用できる、と書かれています。
これを使えば、フロントエンドのプログラムを VS Code でデバッグできるようです。

How to debug frontend through vite on vscode · wailsapp/wails · Discussion #2877 · GitHub

つまり、
①アプリを開発モードで起動する
②これにアタッチする。バックエンドのプログラムがデバッグできる
③開発モードのアプリが起動するウェブサーバにウェブブラウザを起動して開く
④これにアタッチする。フロントエンドのプログラムがデバッグできる

説明③.png

まず、wails dev を VS Code から実行(①)できるように設定を用意します。

tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "wails dev",
      "type": "shell",
      "command": "wails",
      "args": [ "dev" ]
      "options": {
        "cwd": "${workspaceFolder}"
      },
    }
  ]
}

続いて、wails dev で起動したアプリのバックエンドのプログラムにアタッチする(②)設定です。

launch.json
(前略)
    {
      "name": "attach to backend",
      "type": "go",
      "request": "attach",
      "mode": "local",
      "processId": "●●-dev.exe",
    },

proccessId は、実行時点でプロセスを選択させるしかないと思っていましたが、プロセス名で OK でした。wails dev 実行して build/bin フォルダに作成されるアプリの実行ファイルの名前を指定します。↑

続いて、上記のアプリがウェブサーバになるので、ウェブブラウザを起動してフロントエンドのプログラムを開きます(③)。既にアプリが起動してフロントエンドのプログラムの画面が開いていて、これを別にブラウザでフロントエンドの画面を開くので、スマートでありませんが仕方ありません。

launch.json
(前略)
    {
      "name": "launch chrome",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:34115",
      "runtimeArgs": [
        --remote-debugging-port=9222,
      ],
    },

VS Code からアタッチできるよう --remote-debugging-port を指定します。↑

続いて、上記のウェブブラウザで実行しているフロントエンドのプログラムにアタッチする(④)設定です。

launch.json
(前略)
    {
      "name": "attach to chrome",
      "type": "chrome",
      "request": "attach",
      "port": 9222,
      "webRoot": "${workspaceFolder}/frontend",
      "sourceMaps": true,
    },

これを順に実行すればいいのですが、面倒なので連続して実行できないか試してみました。

例えば、上記②の設定に "preLaunchTask": "wails dev" を加えてみたのですが、wails dev が終了して初めて②の設定の attach が実行されるので、これはだめでした。

試行錯誤した結果、以下の設定で使っています。

launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Start Program",
      "type": "node-terminal",
      "request": "launch",
      "command": "wails dev",
      "cwd": "${workspaceFolder}",
    },
    {
      "name": "attach to backend",
      "type": "go",
      "request": "attach",
      "mode": "local",
      "processId": "HelloWails-dev.exe",
      "presentation": {
        "hidden": true,
      }
    },
    {
      "name": "launch chrome",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:34115",
      "runtimeArgs": [
        "--remote-debugging-port=9222",
      ],
      "presentation": {
        "hidden": true,
      }
    },
    {
      "name": "attach to chrome",
      "type": "chrome",
      "request": "attach",
      "port": 9222,
      "webRoot": "${workspaceFolder}/frontend",
      "sourceMaps": true,
      "presentation": {
        "hidden": true,
      }
    },
  ],
  "compounds": [
    {
      "name": "Debug Program",
      "configurations": [
        "attach to backend",
        "launch chrome",
        "attach to chrome",
      ],
      "stopAll": true,
    },
  ],
}

tasks.json でなく launch.jsonwails dev 実行の設定しています。↑

VS Code の「実行とデバッグ」のメニューに Start ProgramDebug Program が表示されます。ビルドして実行してテストするなら Start Program を実行します。実行されたアプリにアタッチしてデバッグするとき Debug Program を実行します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?