README
Things you may want to cover:
Ruby version: 2.5.1
System dependencies: Node.js, Yarn, PostgreSQL, Heroku CLI
Key Dependencies: Ruby on Rails version 5.2, Vue.js version 2.5, Webpacker for Webpack version 4
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
- Update
Gemfile
to use new version:
gem 'webpacker', '>= 4.0.x'
- Install new Webpacker and update application
bundle update webpacker
bundle exec rails webpacker:install:vue
- Upgraded packages by Yarn too
yarn add @rails/webpacker@~4.0.0-pre.2
yarn upgrade webpack-dev-server --latest
yarn install
- Verify that everything is still working
bin/rails test
Use Webpacker
- 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.
- 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' %>
- 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
- 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
- Verify locally that vue.js working
open "http://localhost:3000/"
Expect to see
Setup Heroku and Deploy
- Confirm compilation is working:
RAILS_ENV=production \
NODE_ENV=production \
RAILS_SERVE_STATIC_FILES=true \
SECRET_KEY_BASE="7aa51097e982f34be02abe83528c3308768dff3837b405e0907028c750d22d067367fb79e2b223e3f223fea50ddf2d5dc9b3c933cf5bc8c7f2a3d3d75f73c4a7" \
bin/rails assets:precompile
- 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
- Deploy and verify that vue.js working on Heroku
git push heroku master
heroku apps:open
Setup Vue.js code conventions
- 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
- Update
.babelrc
with:
{
"presets": [
+ "vue-app",
["env", {
"modules": false,
Install Jest for Component Unit Tests
- Add Jest
yarn add --dev jest vue-jest babel-jest @vue/test-utils jest-serializer-vue
- 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",
- 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",
- Add
test/javascript/test.test.js
:
test('there is no I in team', () => {
expect('team').not.toMatch(/I/);
});
- Verify installation
yarn test
You should found
- 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()
})
});
- Verify by
yarn test
You should see all tests passed