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の開発サーバーを起動しておき、そこへリバースプロキシすることで、開発サーバーのホットリロードによる即時反映機能を利用しつつ開発を進めることができます。
事前に別のターミナルから開発用サーバーを起動しておきます。
cd frontend;npm run devmain.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>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その後、Wailsに出会う。
https://zenn.dev/nobonobo/articles/6cc4c510988e82
バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。