こんにちは。現役エンジニアの”はやぶさ”@Cpp_Learningです。Go言語(Golang)やフロントエンドを勉強中です。
GoのソースコードからJavaScriptを生成できるGopherJSについて勉強したので、備忘録も兼ねて本記事を書きます。
Contents
GopherJSとは
GopherJSについて、公式ではGoからJavaScriptへのコンパイラと紹介しています。
GopherJS – A compiler from Go to JavaScript
GopherJS compiles Go code (golang.org) to pure JavaScript code. Its main purpose is to give you the opportunity to write front-end code in Go which will still run in all browsers.
実際に使ってみると、以下の特徴があるので、個人的にはGo to JavaScriptを実現するライブラリ兼アプリという表現の方が”しっくり”きます。
- GopherJSの作法に従って、Goのプログラムを書く必要があり、ライブラリまたはフレームワークという印象
- コンパイラ以外の機能もCLIで提供
GopherJS入門 -環境構築-
最初にDockerでGo開発環境を構築します。以下の記事も参考にして下さい。
まずは適当な場所にプロジェクトフォルダ:docker-gopherjs を作成します。最終的には、以下の構成になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
workspace └─docker_gopherjs ├──Dockerfile # 今回は使わない ├──go.mod ├──go.sum ├──README.md ├──index.html │ ├─css │ └─style.css # 今回は使わない ├─go │ └─app.go │ └──js └─app.js |
DockerでGo開発環境構築
以下のコマンドでGo公式イメージをDocker Hubからpullします。Goの最新バージョンを使いたい人は、タグを 1.17 から latest に変更して下さい。
$ docker pull golang:1.17
ホスト(Windowsマシンとか)とコンテナ間のシェアフォルダで作業するのが好きなので、以下のコマンドでコンテナを起動します。
$ docker run -v [host側のディレクトリパス:コンテナ側のディレクトリパス] -it [イメージ:タグ]
今回は以下の通りです。
$ docker run -v C:/Users/hayab/workspace/docker-gopherjs:/go/src/app -it golang:1.17
pwdを用いた以下のコマンドでもOKです。
$ docker run -v ${pwd}:/go/src/app –name go-goptuna -it golang:1.17
以降からはコンテナに潜って作業します。VSCode拡張機能の Docker 使うのがオススメです。
GopherJSパッケージのインストール
最初に go.mod を作成します。
$ go mod init example.com/myapp
続いて gopherjs をインストールします。
$ go get github.com/gopherjs/gopherjs
gopherjs コマンドを叩いて、コマンド説明などが表示できれば環境構築完了です(下図参照)。
GopherJS入門 -GoからJavaScriptを生成-
以降からはGoのコード書いていきます。
JavaScriptの関数を呼ぶ
js.Global.Call()でJavaScriptの関数を呼ぶことができます。例えば、alert関数を呼ぶときは、以下のように書きます。
1 2 3 4 5 6 7 8 9 10 11 12 |
package main import ( "github.com/gopherjs/gopherjs/js" ) func main() { // アラート表示 // JavaScriptの alert関数:alert('Hello, JavaScript') に相当 js.Global.Call("alert", "Hello, GopherJS!") } |
コンソール出力
コンソール出力は、Go標準パッケージのfmtがそのまま使えます。
1 2 3 4 5 6 7 8 9 10 11 12 |
package main import ( "fmt" ) func main() { // コンソール出力 // JavaScriptの console.log('clicked') に相当 fmt.Println("Hello, JS console") } |
JavaScriptのdocument.hoge()
JavaScriptでいう以下のコードは、js.Global.Get().Call()で対応できます。
- document.write(“Hello world!”)
- document.addEventListener(‘click’, func())
例えば、以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package main import ( "fmt" "github.com/gopherjs/gopherjs/js" ) func callAlert() { // アラート表示 js.Global.Call("alert", "Hello, GopherJS!") } func onClick() { // マウスクリックで自作関数をコール // JavaScriptのdocument.addEventListener('click', func())に相当 js.Global.Get("document").Call("addEventListener", "click", callAlert) } func writeHello() { // JavaScriptの document.write("Hello world!"); に相当 s := "<strong>GoからJavaScriptを生成する!</strong>" js.Global.Get("document").Call("write", s) } func main() { // コンソール出力 fmt.Println("START, App") writeHello() onClick() } |
Goの関数をJavascriptから呼ぶ
Goで作成した自作関数をJavascriptから呼ぶときは、js.Global.Get().Set()を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package main import ( "fmt" "github.com/gopherjs/gopherjs/js" ) func callAlert(s string) { // アラート表示 js.Global.Call("alert", s) // js.Global.Call("alert", "Hello, GopherJS!") // コンソール出力 fmt.Println("Alert! " + s) } func myGoFunc() { // JavaScriptからGoの関数:callAlertを呼べるようにする js.Global.Get("document").Set("myGoFunc", callAlert) } func main() { // コンソール出力 fmt.Println("START, App") myGoFunc() } |
上記のコードをapp.goという名で保存します。
GoからJavaScriptを生成-
先ほど保存したのapp.goからJavaScriptを生成します。
ビルド -Go to JavaScript-
以下のコマンドでapp.goからapp.jsを生成できます。
$ gopherjs build app.go -o ../js/app.js
簡単ですね。
コマンドを忘れたときは、-hを使えば、ガイドしてくれます。
$ gopherjs build -h
index.html
最後に適当なindex.htmlを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>GopherJS テスト</title> <!-- <link rel="stylesheet" href="./css/style.css"> --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/dark.css"> <!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/light.css"> --> <!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1/new.min.css"> --> <!-- <link rel="stylesheet" href="https://siongui.github.io/tipitaka-romn/cscd/tipitaka-latn.css"> --> <script src="./js/app.js"></script> </head> <body> <!-- Add your site or application content here --> <!-- <div id="app"></div> --> <header> <h1>GopherJS テスト</h1> <p>Hello, GopherJS!</p> </header> <h2>GopherJSとは</h2> <a href="https://github.com/gopherjs/gopherjs">GopherJS</a> とは <strong>Go</strong> のソースコードを <strong>JavaScript</strong> に変換するライブラリ兼アプリです。 <p></p> <h2>マウスクリックのイベント駆動</h2> <h3>1. ピュアなJavaScript</h3> <p>以下の<mark>ボタン</mark> をクリックすると、ピュアな<strong>JavaScript</strong>の処理が走ります</p> <button type="button" onclick="alert('Hello, JavaScript!')"> ボタン </button> <!-- <input type="button" name="btn" value="クリック" onclick="btnClick('Hello, JavaScript!')" /> --> <h3>2. GopherJSで生成したJavasSript</h3> 以下の<mark>BUTTON</mark> をクリックすると<strong>GopherJS</strong>で生成した<strong>JavaScript</strong>の処理が走ります</p> <button type="button" onclick="myGoFunc('Hello, GopherJS!')"> BUTTON </button> <!-- <input type="button" name="btn" value="クリック" onclick="myGoFunc('Hello, GopherJS!')" /> --> </body> </html> |
適当なブラウザでindex.htmlを開いて、動作確認したときの様子が以下です。
GoのソースコードからJavaScriptを生成できる GopherJS で遊んでる。 pic.twitter.com/aUCoBvRULn
— はやぶさ@技術ノート (@Cpp_Learning) June 11, 2022
まとめ
GoのソースコードからJavaScriptを生成できるGopherJSについて、色々試した内容をまとめました。本記事が、誰かの参考になれば、嬉しいです。
ただ正直に言えば、Golangもフロントエンドも勉強中なので、中途半端な知識で本記事を書いています。なので不適切な記述があれば、優しく教えて頂けると嬉しいです。
以下 オススメ書籍を紹介