Go 言語だって minify されたい!「mingo」の紹介
HTML/CSS や JavaScript など、 Web フロントエンドにおいては配信時にファイルを minify することが一般的です。
ファイルを minify する = ファイルサイズを小さくすることでネットワークの通信量を削減し、結果として Web ページの読み込み速度を向上させることができます。
<!-- 例えばこれが -->
<!DOCTYPE html>
<html>
<head>
<title>Hello World Sample</title>
</head>
<body>
<h1>Hello, World!</h1>
<button id="button">Click</button>
</body>
<script>
const button = document.getElementById("button");
button.addEventListener("click", function () {
alert("Clicked!");
});
</script>
</html>
<!-- こうなる -->
<!DOCTYPE html><html><head><title>Hello World Sample</title></head><body><h1>Hello, World!</h1><button id="button">Click</button></body><script>const button=document.getElementById("button");button.addEventListener("click",function(){alert("Clicked!");});</script></html>
このように、 Web フロントエンドではパフォーマンス改善を名目として、さも当然のように日々 minify が行われています。
その一方でずっと誰からも minify してもらえずに泣いている言語があります。
ピンときた方も多いと思いますが、そう、 Go 言語です。
ご存知の通り、 Go 言語は基本的に minify されることはありません。
「コンパイル言語だから minify しても意味ないよw」
「どうせビルドしたらバイナリになるんだしw」
そんなふうに Go 言語は長年 minify してもらえることなくひどい差別を受け続けてきました。
果たしてこんな理不尽を許していいのでしょうか。 Go 言語が minify されることを望むのは間違っているのでしょうか。
答えは否です。 Go 言語にも minify される権利はあります。
「たとえ意味がなくとも、 minify されたい」
mingo はそんな Go 言語の切実な願いを叶えるために生まれたツールです。
例えば次のような内容の main.go
があったとします。
package main
import "fmt"
func fib(n int) int {
if n <= 1 {
return n
}
return fib(n-1) + fib(n-2)
}
func main() {
n := 10
for i := 0; i < n; i++ {
fmt.Println(fib(i))
}
}
mingo を使ってみましょう。
# `-w` フラグで上書き
$ mingo -w main.go
main.go
の内容は次のようになりました。
package main;import "fmt";func fib(n int)int{if n<=1{return n};return fib(n-1)+fib(n-2)};func main(){n:=10;for i:=0;i<n;i++{fmt.Println(fib(i))}};
この記事では mingo のインストール方法から基本的な使い方までを紹介します。
mingo の使い方
インストール
Homebrew を使用している場合は brew install
でインストールできます。
$ brew install koki-develop/tap/mingo
もしくは go install
でインストールすることもできます。
$ go install github.com/koki-develop/mingo@latest
Go プログラムを minify する
mingo
コマンドにファイルを渡すだけです。
デフォルトでは minify された内容は標準出力に出力され、ファイルは上書きされません。
$ mingo <ファイル名>
# 例
$ mingo main.go
package main;import "fmt";func fib(n int)int{if n<=1{return n};return fib(n-1)+fib(n-2)};func main(){n:=10;for i:=0;i<n;i++{fmt.Println(fib(i))}};
-w
もしくは --write
フラグをつけるとファイルを上書きできます。
$ mingo -w main.go
# これも同じ
$ mingo --write main.go
ファイルを複数指定することもできます。
$ mingo hoge.go fuga.go
ディレクトリを指定すると、ディレクトリ内の Go ファイルを再帰的に minify します。
# ./some_dir/**/*.go を minify する
$ mingo -w ./some_dir
次のコマンドを実行すれば、カレントディレクトリ内の全ての Go ファイルを minify できます。
$ mingo -w .
実行例
参考までに、 cLive に対して mingo を実行した例がこちらです。
こんな感じ
test も build も通ってる ( lint はしっかりコケてる )
仕組み
これといって特別なことをしているわけではなく、 go/ast
パッケージで Go の抽象構文木を解析して地道にガリガリ書き換えているだけです。
詳しくはソースコードをご参照ください。
まとめ
無意味ですね〜。
Discussion