Movatterモバイル変換


[0]ホーム

URL:


NoboNoboNoboNobo
🦜

Goで軽量なデスクトップアプリ作成

に公開
2023/04/10
2件

Lorca+SvelteKitでやってみる!

あらかじめ必要なもの

  • go(version 1.17.2以降)
  • nodejs(16.9.0以降),npm(7.21.1以降)
  • Chrome/Chromium/Edgeのいずれか

プロジェクトの開始

mkdir sample-guicd sample-guigo mod init sample-guinpm init svelte@next frontend// Choice"Svelte app template" is"Skelton Project".// Choice"Use TypeScript" is No.// Choice"ESLint" is No.// Choice"Prettier" is No.cd frontendnpminstallnpm i-D @sveltejs/adapter-static@nextcd..go get github.com/zserge/lorca@master# masterしかEdgeをみてくれない

svelte.config.jsにスタティックアダプターを追加します。

frontend/svelte.config.js

/** @type {import('@sveltejs/kit').Config} */import adapter from "@sveltejs/adapter-static";const config = {  kit: {    // hydrate the <div> element in src/app.html    target: "#svelte",    adapter: adapter({      // default options are shown      pages: "build",      assets: "build",      fallback: null,    }),  },};export default config;

release.go

//go:build release// +build releasepackage mainimport("embed""io/fs""log""net/http")//go:generate sh -c "cd frontend; npm run build"//go:embed frontend/build/*//go:embed frontend/build/_app/assets/pages/__layout.svelte-*.css//go:embed frontend/build/_app/pages/__layout.svelte-*.jsvar content embed.FSfuncinit(){pub, err:= fs.Sub(content,"frontend/build")if err!=nil{log.Fatal(err)}http.Handle("/", http.FileServer(http.FS(pub)))}

go:embedは、アンダースコアで始まるファイルを埋め込み対象からスキップする挙動がありますので、別途アンダースコアで始まるファイルを追加で名指ししておきます。この問題の別解はfrontend/buildに出力されたファイル群をzipアーカイブにしてからgo:embedで取り込むというものです。

development.go

//go:build !release// +build !releasepackage mainimport("log""net/http""net/http/httputil""net/url")funcinit(){u, err:= url.Parse("http://localhost:3000/")if err!=nil{log.Fatal(err)}http.Handle("/", httputil.NewSingleHostReverseProxy(u))}

開発時はfrontendの開発サーバーを起動しておき、そこへリバースプロキシすることで、開発サーバーのホットリロードによる即時反映機能を利用しつつ開発を進めることができます。

node開発サーバーの起動

事前に別のターミナルから開発用サーバーを起動しておきます。

cd frontend;npm run dev

main実装

main.go

package mainimport("embed""fmt""log""net""net/http""sync""github.com/zserge/lorca")type counterstruct{sync.Mutexcountint}func(c*counter)Add(nint){c.Lock()defer c.Unlock()c.count= c.count+ n}func(c*counter)Value()int{c.Lock()defer c.Unlock()return c.count}funcmain(){log.SetFlags(log.Llongfile)ui, err:= lorca.New("","",480,320)if err!=nil{log.Fatal(err)}defer ui.Close()ui.Bind("start",func(){log.Println("UI is ready")})c:=&counter{}ui.Bind("counterAdd", c.Add)ui.Bind("counterValue", c.Value)ln, err:= net.Listen("tcp","127.0.0.1:0")if err!=nil{log.Fatal(err)}defer ln.Close()go http.Serve(ln,nil)ui.Load(fmt.Sprintf("http://%s/", ln.Addr()))ui.Eval(`console.log("Hello, world!");`)<-ui.Done()}

起動

go run.

翻訳オファーダイアログ対策

SvelteKitテンプレートのままだと翻訳オファーのダイアログが表示される場合があります。
その場合、app.htmlに以下の三行を追加しておくことで抑制できます。

<htmllang="ja"><head><metahttp-equiv="Content-Language"content="ja"/><metaname="google"content="notranslate"/>    ...</head>  ...</html>

ヒストリ機能が邪魔な場合

app.htmlに以下のスクリプトを追記しよう!
これで戻る・進むで何も変化しなくなります。

<htmllang="ja"><head>  ...</head><body>  ...</body><script>    history.pushState(null,null,null);window.addEventListener("popstate",(e)=>{      history.pushState(null,null,null);      e.preventDefault();});</script></html>

コンテキストメニューが邪魔な場合

app.htmlに以下のスクリプトを追記しよう!
右クリックメニューが表示できなくなります。
(上記もやっておくとキーショートカットで戻ったり進んだりもできない)

<htmllang="ja"><head>  ...</head><body>  ...</body><script>window.addEventListener("contextmenu",(e)=>{      e.preventDefault();});</script></html>

2本指またはタッチパネルのスワイプを無効化

app.htmlのbodyタグに以下のスタイルを追記しよう!

<bodystyle="overscroll-behavior-x: none">

ファイル一覧

サンプルソース(時計):https://github.com/nobonobo/clock

├── frontend/
│   ├── README.md
│   ├── build/
│   ├── jsconfig.json
│   ├── node_modules/
│   ├── package-lock.json
│   ├── package.json
│   ├── src/
│   ├── static/
│   └── svelte.config.js
├── go.mod
├── go.sum
├── development.go
├── release.go
└── main.go

ビルド

go generate-tags releasego build-tags releasels-lh sample-gui-rwxr-xr-x@1 nobo  staff7.3M101722:48 sample-gui

まとめ

  • コンテンツ込みで約7Mバイト前後のサイズ
  • Electronと違いビルド速度、実行速度ともに早い
  • macOS/Linux/WindowsとPC-OS環境を選ばず動く
  • JSコンテキストにGoの処理関数を埋め込むことができる。
  • Chrome/Chromium/Edgeのいずれもインストールされていない環境はレアケース
  • ただのWebページなので任意のJSフロントエンド技術が使える
  • 多言語圏で鍛えられたブラウザエンジンを利用するので日本語表示や日本語入力で困ることもない
  • LorcaとSvelteKit双方シンプルなアプローチによるコンセプトの相性は良さそう

追記

その後、Wailsに出会う。
https://zenn.dev/nobonobo/articles/6cc4c510988e82

NoboNobo

Pythonista で近年はGo言語にハマっています。

バッジを贈って著者を応援しよう

バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。

NoboNoboNoboNobo

多大な労力で作られるクロスプラットフォームGUIフレームワークの多くは日本語圏の課題修正は後回しになりがちで、どんなに良さそうに見えても日本語入力に問題があることで採用できないということが起こりうるし、レイアウトエンジンの挙動やWidgetsの組み方、制約などを学び直しになることが多いのでこの手法ならつまづきなく作り込みができるかなぁと思ったのですー。

3
NoboNoboNoboNobo

あとは以下のことができるといいのかな?

  • Windowsアイコンリソースの割り当て
  • macOSのアイコンとApp化
  • Ubuntuのアイコンと.desktopファイル作成
1

[8]ページ先頭

©2009-2025 Movatter.jp