go gin + React でウェブページを表示する

皆さん、お疲れ様です。
最近益々寒くなって来ましたね。大阪に来て2度めの越冬ですが、大阪は雪が全然降りませんね。地元はかなりの豪雪地帯だったので、嬉しくもあり、寂しくもあります。
寒いときはやはり蕎麦ですね。蕎麦は全季節対応型で美味しいです。

 さて、今回は題名の通りですが、go gin + React でWebページを表示する備忘録的なものです。私はどちらも初心者of初心者なので、なにか間違ってることがあるかもしれませんが、ご容赦の程を……

今回のディレクトリ構成

go-react/
 ├ assets/
 │ ├ css/
 │   └ style.css
 │ ├ js/
 │ └ src/
 │   └ js/
 │      └ go-react.js
 ├ templates/
 │ └ top/
 │   └ index.html
 ├ webpack.config.js
 └ main.go

とりあえず gin でHTMLを表示する

以下、ソースコード

main.go

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()
	router.LoadHTMLGlob("templates/**/*")
	router.Static("/assets", "./assets")

	router.GET("/", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "top/index.html", gin.H{})
	})
	router.Run(":8080")
}

index.html

{{ define "top/index.html" }}
<head>
<meta charset="utf-8">
<title>Index</title>
<link rel="stylesheet" href="/assets/css/style.css">
</head>

<body>
    <h1>Hoge</h1>
</body>
{{ end }}

style.css

h1 {
    font-size: 48pt;
    color: red;
}

こんな感じです。
あとは go run main.go して http://localhost:8080 にアクセスしたらCSSが適用された画面が表示されるはずです。

個人的にハマったところは、HTMLファイルの頭に {{ define “top/index.html” }} みたいな文字列を追加しないと、階層になったフォルダからHTMLが読み込まれないという所ですかね。
チュートリアルのコードそのまま改造する感じでやってたので、一回ディレクトリ構成を変更するととたんにボロがでちゃいました…

webpack.config.jsを設定する

webpack.config.js

var debug   = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path    = require('path');

module.exports = {
  context: path.join(__dirname, "assets"),
  entry: "./src/js/go-react.js",
  module: {
    rules: [{
      test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: [{
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-react', '@babel/preset-env']
          }
        }]
      }]
    },
    output: {
      path: __dirname + "/assets/js/",
      filename: "go-react.min.js"
    },
    plugins: debug ? [] : [
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
    ]
};

https://qiita.com/TsutomuNakamura/items/72d8cf9f07a5a30be048
こちらのページを参考にさせて頂いています。

あとは、

npm init

します。webpack.config.js はすでに作っておいたのでエンターキー連打で大丈夫です。

React (Babel) のインストールは省略します。

React をトランスパイルする

最初の index.html を以下のように変更します

{{ define "top/index.html" }}
<head>
<meta charset="utf-8">
<title>Index</title>
<link rel="stylesheet" href="/assets/css/style.css">
</head>

<body>
    <div id="output"></div>
    <script src="go-react.min.js"></script>
</body>
{{ end }}

go-react.js は次のようにします

import React from "react";
import ReactDOM from "react-dom";

class Layout extends React.Component {
  render() {
    return (
      <h1>Fuga</h1>
    );
  }
}

const app = document.getElementById('output');
ReactDOM.render(<Layout/>, app);

後は

webpack --mode development

でトランスパイルします。

あとは go run main.go して http://localhost:8080 にアクセスするとReactによるレンダリングが行われると思います。

あとがき

フロントエンドフレームワークをろくに触ったことがなかったので、Reactを勉強してるととても新鮮です。
結構躓くことは多いですがその時はまたブログのネタにします……