GOで画像やHTMLを扱う時にシングルバイナリ化することで簡単にリリースできるようにしたい。
以前スマホアプリ制作用にgo-assets-builderを使ってバイナリ化したことがありますが、他の方法も検討してみて使ってみます。
バイナリ化パッケージ
基本的にはファイルをバイナリ化して変数に格納してそれを使う形です。
なのでバイナリ化する部分とバイナリ化したものを使う部分に分かれています。
go-bindata | N/A | ググると大体これを使っている印象。
制作者が停止したためレポジトリはアーカイブ。 メンテナンスはされておらず今後もない。 |
go-assets-builder | ★185 | go-bindataが終了状態のため代替手段として紹介されているのを見つけて使っていたが、こちらもずっとメンテナンスされていない。 |
statik | ★1943 | 現在もメンテナンスされている。
現状だとこれ1択かもしれない。 |
statikがシンプルで人気があるようなので使ってみる。
statikの使い方
1 2 3 4 5 6 |
//パッケージのインストール //statikコマンドを使えるようになる go get github.com/rakyll/statik //assetフォルダをgoファイル化する statik asset |
go-assetsはデフォルトでmainパッケージにgoファイルを作るのでビルド時にメディアファイルを指定する方法だった。
statikはデフォルトでstatikパッケージを作るのでインポートして使う形になる。
※どちらもフラグでパッケージ指定可能
個人的にはこちらの方が自然で扱いやすいように思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import ( "github.com/rakyll/statik/fs" _ "./statik" // TODO: Replace with the absolute import path ) //... statikFS, err := fs.New() if err != nil { log.Fatal(err) } //os.Openのようにファイル読み込みに使う f, err := statikFS.Open("/test.jpg") if err != nil { log.Fatal(err) } defer f.Close() //FileSystemとしてそのまま使う http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(statikFS))) |
go moduleを使う場合にはimportでの絶対パスは必須です。
webフレームワーク ginとの合わせ
ginでシングルバイナリ化を考えると静的ファイルであればファイルシステムの指定が可能です。
1 |
r.StaticFS("/static", statikFS) |
しかしLoadHTMLGlob()
(あるいはLoadHTMLFiles
)を考えると少し面倒そうです。
template
が指定したファイルシステムから読み込んでパースする方法がなさそう。
この辺を見てうまいこと置き換えできないかと考えてますが、一つ一つ開いて文字列からパースしないといけない気がする(関数の追加が必要そう)。
テンプレートは大分癖があるのでHTMLはjavascriptフレームワークに任せて、静的ファイルとAPIの管理だけする方がやはり楽か。
追記
1年ほど前の記事ですがいい感じの比較があったので追記します。