This article describes how to build and develop Web application with Go + gin-gonic (Web Application Framework in Go) + Vue.
(Edited) Sample code repository: https://github.com/m-mizutani/web-app-go
Steps
Configure webpack
At first, install yarn packages
$ yarn init
$ yarn add -D @babel/cli @babel/core @babel/preset-env babel-loader webpack webpack-cli webpack-dev-server html-webpack-plugin vue-loader vue-template-compiler css-loader vue-style-loader sass-loader
$ yarn add babel-polyfill vue node-sass axios
After that, create webpack.config.js
file.
const path = require('path');
const VueLoaderPlugin = require("vue-loader/lib/plugin");
module.exports = {
mode: "development",
entry: ["babel-polyfill", path.resolve("src", "js", "index.js")],
output: {
filename: "bundle.js",
path: path.join(__dirname, "static/js/"),
publicPath: "/js"
},
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.js$/,
loader: "babel-loader"
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'vue-style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
}
]
},
resolve: {
extensions: [".js", "json", "jsx", "vue"],
alias: {
vue$: "vue/dist/vue.esm.js"
}
},
devServer: {
contentBase: "static",
proxy: {
"/api": "http://localhost:9080"
}
},
plugins: [new VueLoaderPlugin()]
};
Additoinaly, put following setting into package.json
.
"scripts": {
"start": "webpack-dev-server",
"build": "webpack --optimize-minimize"
},
Add web assets
Required following files:
src/css/main.scss
src/js/index.js
src/js/app.vue
static/index.html
main.scss
body {
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
}
index.js
import '../css/main.scss'
import _ from 'lodash';
import "babel-polyfill";
import Vue from "vue";
import App from "./app.vue";
new Vue({
el: "#app",
render: h => h(App)
});
app.vue
<template>
<div>
<div>MyApp</div>
<button v-on:click="showMessage">This is test</button>
<div>{{message}}</div>
</div>
</template>
<script>
import axios from "axios";
const appData = {
message: ""
};
export default {
data() {
return appData;
},
methods: {
showMessage: showMessage
}
};
function showMessage() {
axios.get("/api/v1/hello").then(res => {
console.log(res);
appData.message = res.data.message;
});
}
</script>
<style>
</style>
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>MyApp</title>
</head>
<body>
<div id="app"></div>
<script src="/js/bundle.js"></script>
</body>
</html>
Add go module
Initialize go module.
$ go mod init github.com/m-mizutani/web-app-go
After that, add main.go.
package main
import (
"fmt"
"os"
"github.com/gin-contrib/static"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
var logger = logrus.New()
var logLevelMap = map[string]logrus.Level{
"trace": logrus.TraceLevel,
"debug": logrus.DebugLevel,
"info": logrus.InfoLevel,
"warn": logrus.WarnLevel,
"error": logrus.ErrorLevel,
}
type arguments struct {
LogLevel string
BindAddress string
BindPort int
StaticContents string
}
func runServer(args arguments) error {
level, ok := logLevelMap[args.LogLevel]
if !ok {
return fmt.Errorf("Invalid log level: %s", args.LogLevel)
}
logger.SetLevel(level)
logger.SetFormatter(&logrus.JSONFormatter{})
logger.WithFields(logrus.Fields{
"args": args,
}).Info("Given options")
r := gin.Default()
r.Use(static.Serve("/", static.LocalFile(args.StaticContents, false)))
r.GET("/api/v1/hello", func(c *gin.Context) {
c.String(200, `{"message":"hello, hello, hello"}`)
})
if err := r.Run(fmt.Sprintf("%s:%d", args.BindAddress, args.BindPort)); err != nil {
return err
}
return nil
}
func main() {
args := arguments{
LogLevel: "info",
BindAddress: "0.0.0.0",
BindPort: 9080,
StaticContents: "./static",
}
if err := runServer(args); err != nil {
logger.WithError(err).Fatal("Server exits with error")
}
}
Development
Run go server
$ go run .
air command with .air.conf
like following is recommended for hot reloading.
[build]
include_ext = ["go", "tpl", "tmpl", "html"]
exclude_dir = ["src", "tmp", "node_modules"]
delay = 1000 # ms
stop_on_error = true
log = "air_errors.log"
And run air
$ air -c .air.conf
Start webpack development server
$ npm run start
Open browser
Open http://localhost:8080 to confirm Web UI.
Deploy
$ npm run build
$ go build -o sercer
$ cp -r server static /path/to/server
Top comments (3)
thanks for your post, I'm learning go and it seems good to start with.
Can please upload the code to some repo? thanks.
Learning go? Maybe try go–on–aws.com?
Thank you for your comment. I added sample code repository URL (github.com/m-mizutani/web-app-go) to head of the post.