Get your Rails app off the ground, fast

Vue JS + Rails 5

README

Things you may want to cover:

Generate Ruby on Rails Project with Vue.js (No Turbolinks included on this stage)

gem install rails -v 5.2

rails new vuejs-ror-setup -M -C -S --skip-turbolinks --webpack=vue -d postgresql
cd ./vuejs-ror-setup

bin/setup
bin/update

bin/rails test

Upgrade to Webpacker 4

  1. Update Gemfile to use new version:
gem 'webpacker', '>= 4.0.x'
  1. Install new Webpacker and update application
bundle update webpacker
bundle exec rails webpacker:install:vue
  1. Upgraded packages by Yarn too
yarn add @rails/webpacker@~4.0.0-pre.2
yarn upgrade webpack-dev-server --latest
yarn install
  1. Verify that everything is still working
bin/rails test

Use Webpacker

  1. Enable unsafe-eval rule to support runtime-only build

This can be done in the config/initializers/content_security_policy.rb with the following configuration:

Rails.application.config.content_security_policy do |policy|
  if Rails.env.development?
    policy.script_src :self, :https, :unsafe_eval
  else
    policy.script_src :self, :https
  end
end

You can learn more about this from: Vue.js Docs and Webpacker/Vue Docs.

  1. Enable Webpacker by updating app/views/layout/application.html.erb:
-    <%= stylesheet_link_tag    'application', media: 'all' %>
-    <%= javascript_include_tag 'application' %>
+    <%= stylesheet_pack_tag 'hello_vue', media: 'all' %>
+    <%= javascript_pack_tag 'hello_vue' %>
  1. Add sample page to confirm that Vue.js loaded:
bin/rails g controller Hello index --no-javascripts --no-stylesheets --no-helper --no-assets --no-fixture
bin/rails s
  1. Setup sample page as home page by updating config/routes.rb:
 Rails.application.routes.draw do
+  root 'hello#index'
+
   get 'hello/index'   
   # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
 end
  1. Verify locally that vue.js working

open "http://localhost:3000/"

Expect to see

Setup Heroku and Deploy

  1. Confirm compilation is working:
RAILS_ENV=production \
NODE_ENV=production \
RAILS_SERVE_STATIC_FILES=true \
SECRET_KEY_BASE="7aa51097e982f34be02abe83528c3308768dff3837b405e0907028c750d22d067367fb79e2b223e3f223fea50ddf2d5dc9b3c933cf5bc8c7f2a3d3d75f73c4a7" \
bin/rails assets:precompile
  1. Create Heroku App and provision it

Requirements: Heroku CLI

heroku create

heroku buildpacks:add heroku/ruby

heroku config:set RAILS_ENV=production NODE_ENV=production
  1. Deploy and verify that vue.js working on Heroku
git push heroku master

heroku apps:open

Setup Vue.js code conventions

  1. Install vue.js official babel preset

NOTE: Ruby on Rails + Webpacker do not support babel presets installed in development dependencies.

yarn add babel-preset-vue-app
  1. Update .babelrc with:
 {
   "presets": [
+    "vue-app",
     ["env", {
       "modules": false,

Install Jest for Component Unit Tests

  1. Add Jest
yarn add --dev jest vue-jest babel-jest @vue/test-utils jest-serializer-vue
  1. Update package.json
 {
   "name": "vuejs-ror-setup",
   "private": true,
+  "scripts": {
+    "test": "jest"
+  },
+  "jest": {
+    "roots": [
+      "test/javascript"
+    ],
+    "moduleDirectories": [
+      "node_modules",
+      "app/javascript"
+    ],
+    "moduleNameMapper": {
+      "^@/(.*)$": "app/javascript/$1"
+    },
+    "moduleFileExtensions": [
+      "js",
+      "json",
+      "vue"
+    ],
+    "transform": {
+      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
+      ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
+    },
+    "snapshotSerializers": [
+      "<rootDir>/node_modules/jest-serializer-vue"
+    ]
+  },
   "dependencies": {
     "@rails/webpacker": "^3.4.1",
  1. Update .babelrc:
   "presets": [
     "vue-app",
     ["env", {
       "modules": false,
       "targets": {
         "browsers": "> 1%",
         "uglify": true
       },
       "useBuiltIns": true
     }]
   ],   
+  "env": {
+    "test": {
+      "presets": [
+        ["env", {
+          "targets": {
+            "node": "current"
+          }
+      }]]
+  }},
   "plugins": [
     "syntax-dynamic-import",
     "transform-object-rest-spread",
  1. Add test/javascript/test.test.js:
test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});
  1. Verify installation
yarn test

You should found

  1. Add component test for App in test/javascript/app.test.js:
import { mount, shallowMount } from '@vue/test-utils'
import App from 'app';

describe('App', () => {
  test('is a Vue instance', () => {
    const wrapper = mount(App)
    expect(wrapper.isVueInstance()).toBeTruthy()
  })

  test('matches snapshot', () => {
    const wrapper = shallowMount(App)
    expect(wrapper.html()).toMatchSnapshot()
  })
});
  1. Verify by
yarn test

You should see all tests passed

Jun 08
Jun 09
Jun 10
Jun 11
Jun 12
Jun 13
Jun 14
Jun 15
15
16
17
Stars
Jun 08
Jun 09
Jun 10
Jun 11
Jun 12
Jun 13
Jun 14
Jun 15
3
4
5
Forks
Jun 08
Jun 09
Jun 10
Jun 11
Jun 12
Jun 13
Jun 14
Jun 15
6
7
8
Issues