Getting started with goBuffalo and Vue.js
in Software on November 16, 2019 | Go GoBuffalo Webpack Vue.js Jest Travis-Ci Coveralls Docker
This is the first part of a guide intended to assist in start a new Vue.js project ontop of Buffalo. In this first part we will integrate Vue.js into the Buffalo asset pipeline, adjust the tests and create a base to begin development upon in the next post.
Prerequisites
- Install Golang
- Install Buffalo
- Install Postgresql
- Install Docker
- Install Vue/cli
Sections
- Prerequisites
- Integrating Vue.js into Buffalo asset pipeline
- Create Vue app placeholder
- Setup Vue.js testing with Jest
- Exploring the Buffalo test tooling
- Creating and running the Docker image
- Enable Travis-CI
- Enable Coveralls
Generate application
# Generate a buffalo app
buffalo new myapp && cd myapp
# Generate pop config
buffalo pop g config
# Create databases with pop
buffalo pop create -a
If the pop commands fail and you have postgresql installed and running you likely have not granted the proper permissions. You will need to adjust the pg_hba.conf
file to fit your scenario.
Integrating Vue.js into Buffalo asset pipeline
The Buffalo asset pipeline is just webpack. So we’re going to simply apply a manual setup of vue-loader.
# sudo yarn global add @vue/cli
yarn add vue vue-loader vue-router vue-template-compiler
Modify webpack.config.js
The resolve alias is for cleaner import statements in our application.js file later on.
// ...
const VueLoaderPlugin = require('vue-loader/lib/plugin');
// ...
const configurator = {
// ...
plugins() {
var plugins = [
// ...
new VueLoaderPlugin(),
// ...
];
// ...
},
// ...
moduleOptions: function() {
return {
rules: [
// ...
{ test: /\.vue/, loader: "vue-loader" },
// ...
]
}
},
// ...
buildConfig: function(){
// ...
var config = {
// ...
resolve: {
// ...
alias: {
vue$: `${__dirname}/node_modules/vue/dist/vue.esm.js`,
router$: `${__dirname}/node_modules/vue-router/dist/vue-router.esm.js`
}
}
}
// ...
}
}
// ...
Create Vue app placeholder
We are going to replace the generated front-end with a Vue app that has a single index route and add routes to get there.
Modify actions/app.go
Add a route to access the Vue app
// ...
func App() *buffalo.App {
if app == nil {
// ...
app.GET("/", HomeHandler)
app.ServeFiles("/", assetsBox) // serve files from the public directory
}
// ...
}
// ...
Some tutorials recommend using app.GET("/{path:.+}", HomeHandler)
to capture all requests and send them to the Vue app. Due to the way ServeFiles
works (I think this was changed at some point but was unable to find the version it happened) you can’t really have a catch all route off the index. One way to get around this would be to nest your application in a path like "/app/{path:.+}"
. This is probably a fine solution but I care about my urls too much so for this guide we will create a more verbose routes list than we would normally have to with Buffalo.
Remove generated Buffalo templates
rm templates/_flash.plush.html
rm templates/index.plush.html
Modify templates/application.plush.html
Remove the flash partial call from this file.
<%= partial("flash.html") %>
Create templates/index.html
<div id="app">
<router-view></router-view>
</div>
Modify actions/home_test.go
At this point our tests are broken but we can fix them. home_test.go
checks the contents of the home handler and we’ve altered it. Lets change "Welcome to Buffalo"
to "<div id=\"app\">"
.
Create assets/js/pages/home.vue
<template>
<div>
<h1 class="page-header">Welcome</h1>
</div>
</template>
<script charset="utf-8">
export default {
data() {
return { };
},
created() { },
watch: { },
methods: { }
};
</script>
Modify assets/js/application.js
require("expose-loader?$!expose-loader?jQuery!jquery");
require("bootstrap/dist/js/bootstrap.bundle.js");
import Vue from "vue";
import VueRouter from "router";
import HomePage from "./pages/home.vue";
$(() => {
Vue.use(VueRouter);
const routes = [
{path: "/", component: HomePage}
];
const router = new VueRouter({
mode: "history",
routes
});
const app = new Vue({
router
}).$mount("#app");
});
At this point your tests should pass with buffalo test
and you can access your Vue app via buffalo dev
.
Setup Vue.js testing with Jest
yarn add --dev jest vue-jest babel-core@bridge @vue/test-utils
Modify the package.json
Configure Jest.
{
// ...
"scripts": {
// ...
"test": "jest"
},
// ...
"jest": {
"moduleFileExtensions": [ "js", "json", "vue" ],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "vue-jest"
}
}
}
Create assets/js/test/unit/home.spec.js
import { shallowMount } from '@vue/test-utils'
import HomePage from "../../pages/home.vue";
let wrapper = null
beforeEach(() => {
wrapper = shallowMount(HomePage)
})
afterEach(() => {
wrapper.destroy()
})
describe('Home', () => {
it('renders Welcome', () => {
expect(wrapper.find('.page-header').text()).toContain('Welcome')
})
})
Running Vue.js tests
yarn test
Exploring the Buffalo test tooling
Code coverage
# Generate a coverage profile
buffalo test -covermode=count -coverprofile=c.out ./...
# You can get a really nice visualization of tested code with the cover tool
go tool cover -html=c.out
If you’re on WSL you can use wslpath -w
to convert the file path to one you can use in your windows browser.
Race condition detection
buffalo test -race ./...
Run a single test
buffalo test -m "FooMethod"
Test everything
This runs your tests and dependancy tests and is usually only done before publishing an application as it takes quite a long time.
buffalo test all
Creating and running the Docker image
Buffalo generated a docker file for us when we created our appplication. Let’s build it with:
docker build . -t myapp
Before running our Docker image we will likely need to change our postgresql configuration to allow connections from the container. This is very dependant on where and how you are running your local postgresql for development. I am running my postgres on localhost so I was able to follow these instructions.
Running the image
docker run -it -p "3000:3000" myapp
You should be able to access your app from the browser via http://localhost:3000.
Enable Travis-CI
Follow this guide to give travis permissions to your repository.
Create .travis.yml
dist: bionic
services:
- postgresql
addons:
postgresql: 10
language: go
go:
- 1.12.x
# Force-enable Go modules. This will be unnecessary when Go 1.14 lands.
env: GO111MODULE=on
# Only clone the most recent commit.
git:
depth: 1
before_script:
# Install buffalo
- wget https://github.com/gobuffalo/buffalo/releases/download/v0.15.1/buffalo_0.15.1_linux_amd64.tar.gz
- tar -xvzf buffalo_0.15.1_linux_amd64.tar.gz
- sudo mv buffalo /usr/local/bin/buffalo
# Install goveralls to push code coverage to coverage.io
- go get github.com/mattn/goveralls
script:
- go vet ./...
- buffalo test -covermode=count -coverprofile=c.out ./...
- yarn install --no-progress
- yarn test
- buffalo build --static
after_script:
- $GOPATH/bin/goveralls -coverprofile=c.out -service=travis-ci
- cat ./coverage/lcov.info | yarn run coveralls
Enable Coveralls
Give coveralls.io permissions to your repository.
yarn add --dev coveralls
Modify .travis.yml
# ...
before_script:
# ...
# Install goveralls to push code coverage to coverage.io
- go get github.com/mattn/goveralls
# ...
after_script:
- $GOPATH/bin/goveralls -coverprofile=c.out -service=travis-ci
- cat ./coverage/lcov.info | yarn run coveralls
Thank you
Your comment has been submitted and will be published once it has been approved.
OOPS!
Your comment has not been submitted. Please go back and try again. Thank You!
If this error persists, please open an issue by clicking here.
Say something