5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

lorca + Reactで作る簡単デスクトップアプリ

Last updated at Posted at 2018-12-24

この記事はあくあたん工房AdventCalendar24日目の記事です.

はじめに

Electronより軽量なHTML5デスクトップアプリ用ライブラリとして最近注目されているlorcaを使ってデスクトップアプリを作っていきます.
やることは簡単で,

  • Reactで適当なSPAを作る
  • Ginで静的ファイルを配信するエンドポイントを立てる
  • lorcaでそれを見る

という感じです.

lorca

READMEより
A very small library to build modern HTML5 desktop apps in Go. It uses Chrome browser as a UI layer. Unlike Electron it doesn't bundle Chrome into the app package, but rather reuses the one that is already installed. Lorca establishes a connection to the browser window and allows calling Go code from the UI and manipulating UI from Go in a seamless manner.

上記のとおり,Electronと決定的に違うのは,ユーザーがすでにインストールしているChromeをUIレイヤーとして活用するという点です.
これによって生成されるアプリケーションのサイズが軽量になります.
(もちろん,Chromeのタブの1つとして動作しているのでElectronより機能はかなり制限されています. e.g window menuが無い)

ただ,GoのコードとJSのコードを紐付けることができるので,GoのCLIアプリをGUI化するときにめっちゃ役立ちそうです.今回は使いませんが.

作っていく

最初のリポジトリ構造はこれ

.
├── LICENSE
├── README.md
├── go.mod
├── go.sum
└── main.go

この中にcreate-react-appでReactアプリを作ります.

$ create-react-app app
$ tree . -I node_modules
.
├── LICENSE
├── README.md
├── app
│   ├── README.md
│   ├── build
│   │   ├── asset-manifest.json
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── manifest.json
│   │   ├── precache-manifest.1b7c797c02d13deffb0ad84befafc406.js
│   │   ├── service-worker.js
│   │   └── static
│   │       ├── css
│   │       │   ├── main.5be34591.chunk.css
│   │       │   └── main.5be34591.chunk.css.map
│   │       ├── js
│   │       │   ├── 1.fa92c112.chunk.js
│   │       │   ├── 1.fa92c112.chunk.js.map
│   │       │   ├── main.88557385.chunk.js
│   │       │   ├── main.88557385.chunk.js.map
│   │       │   ├── runtime~main.229c360f.js
│   │       │   └── runtime~main.229c360f.js.map
│   │       └── media
│   │           └── logo.5d5d9eef.svg
│   ├── package.json
│   ├── public
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   └── manifest.json
│   ├── src
│   │   ├── App.css
│   │   ├── App.js
│   │   ├── App.test.js
│   │   ├── index.css
│   │   ├── index.js
│   │   ├── logo.svg
│   │   └── serviceWorker.js
│   └── yarn.lock
├── go.mod
├── go.sum
└── main.go

yarn buildするとbuildディレクトリにwebpack後のファイルが展開されるので,これを配信するサーバーとそれをlorcaで参照する処理を書いていきます.

main.go
package main

import (
	"log"

	"github.com/gin-contrib/static"
	"github.com/gin-gonic/gin"
	"github.com/zserge/lorca"
)

var staticDir = "./app/build"

func main() {
	go runServer()

	err := runUI()
	if err != nil {
		log.Fatal(err)
	}
}

// app/build/以下を配信するサーバー
func runServer() {
	router := gin.Default()
	router.Use(static.Serve("/", static.LocalFile(staticDir, true)))
	err := router.Run(":9000")
	if err != nil {
		log.Fatal(err)
	}
}

// lorca起動
func runUI() error {
	ui, err := lorca.New("", "", 320, 480)
	if err != nil {
		return err
	}

	ui.Load("http://localhost:9000")
	<-ui.Done()
	return nil
}

実行するとcreate-react-app直後のお馴染みの画面がデスクトップアプリのような形で表示されると思います.

$ go run main.go

スクリーンショット 2018-12-24 18.57.46.png

おぉ〜.

1つのデスクトップアプリケーションとしてパッケージ化する

公式のexampleにあるcounterを見てもらうと分かりますが,Windows,MacOS,Linuxごとにアプリをパッケージ化できるようなシェルスクリプトが書いてあります.
パクり参考にしながら今回の構成に合わせるとこんな感じになります.

build-macos.sh
#!/bin/sh

APP="Example.app"
mkdir -p $APP/Contents/{MacOS,Resources}
go build -ldflags "-X main.staticDir=$(pwd)/Example.app/Contents/Resources/app" -o $APP/Contents/MacOS/lorca-example 
cat > $APP/Contents/Info.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>lorca-example</string>
	<key>CFBundleIconFile</key>
	<string>icon.icns</string>
	<key>CFBundleIdentifier</key>
	<string>com.zserge.lorca.example</string>
</dict>
</plist>
EOF
cp icons/icon.icns $APP/Contents/Resources/icon.icns
cp -r app/build/ $APP/Contents/Resources/app
find $APP

-ldfragsで埋め込んでるリソースのパス指定の方法が良くないですね.はい.
というかシングルバイナリ化したほうがいいのでしょうか?

スクリプトを走らせると,Example.appができているはずです.
スクリーンショット 2018-12-24 20.31.51.png

おわりに

今回のリポジトリはこちら : taxio/temo
本当はMacOS用の簡単なメモ帳アプリを作りたかったんですが,クリスマスケーキとチーズフォンデュが僕を呼んでいるので今日はここまで.

リポジトリのコードはちょくちょく更新していきます.

5
3
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
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?