Giter VIP home page Giter VIP logo

jetthoughts / vuejs-rails-starterkit Goto Github PK

View Code? Open in Web Editor NEW
218.0 16.0 36.0 2.1 MB

Vue.js + Rails Starting Kit GitHub Template to develop Hybrid Mobile Application: https://vuejs-rails-starterkit.herokuapp.com

Home Page: https://jtway.co

License: MIT License

Ruby 58.75% JavaScript 12.32% CSS 1.10% Vue 0.40% HTML 22.40% Shell 4.53% SCSS 0.50%
vue verify ruby rails heroku boilerplate-template nodejs rails5 hackathon rails-boilerplate

vuejs-rails-starterkit's Introduction

Rails 6 + Vue.js 2 Starter Kit GitHub Template.

NOTE: For Rails 5.2, please check https://github.com/jetthoughts/vuejs-rails-starterkit/tree/rails-5-latest

Deploy GitHub Actions Test CircleCI Test codecov

A quick and easy way to setup Rails + PWA + Turbolinks + Webpacker + Bootstrap with AdminLTE theme + Vue + Jest. If your team is considering or has already decided to use Vue, this is the right for you. As an additional review of how to setup PWA, Turbolinks, CSS frameworks, Storybook.

Preview of all steps

asciicast

Expected Final Screen

image

Table of Contents

Things you may want to cover:

Features:

  • Optimized for peformance Webpacker with Vue.js: Lazy Load, Split Chunks
  • Turbolinks
  • PWA
  • Backend Unit and System Tests with coverage
  • Vue.js Unit Tests with coverage
  • Deployable to Heroku
  • Pre-setup for services:
    • GitHub
    • Heroku (Heroku Reviews Apps)
    • CircleCI
    • Codecov and Simplecov
    • Dependabot
  • Static Code Analyzers:
    • Pronto
    • Rubocop
    • ESLint
    • EditorConfig

Dependencies:

System Dependencies:

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

gem install rails

rails new vuejs-rails-starterkit --force --database=postgresql \
  --skip-action-mailer --skip-action-cable --skip-sprockets --skip-turbolinks \
  --webpack=vue

cd ./vuejs-rails-starterkit

bin/rails db:create db:migrate

This generates Rails project with:

  • Vue component in app/javascript/app.vue
  • Example entry file app/javascript/packs/hello_vue.js

Setup development environment:

  1. Uncomment system('bin/yarn') in bin/setup and bin/update to install new node modules.

  2. Install dependencies:

bin/setup
  1. Enable content_security_policy in the config/initializers/content_security_policy.rb with the following configuration:
Rails.application.config.content_security_policy do |policy|
  policy.script_src :self, :https

  if Rails.env.development? || Rails.env.test?
    policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035'
  end
end
  1. Verify that we have not broken anything
bin/webpack
bin/rails runner "exit"

Add sample page to host Vue.js component

  1. Generate controller and view:
bin/rails generate controller Landing index --no-javascripts --no-stylesheets --no-helper --no-assets --no-fixture
  1. Update app/views/landing/index.html.erb to:
<h1>Landing#index</h1>
<p>Find me in app/views/landing/index.html.erb</p>

<div id='hello_vue_app'></div>
  1. Change app/javascript/packs/hello_vue.js to:
import Vue from 'vue'
import App from '../app.vue'

document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    render: h => h(App),
    el: '#hello_vue_app'
  }).$mount()
})
  1. Setup a sample page as a home page by updating config/routes.rb:
  root 'landing#index'

Use Webpacker assets in the application

  1. Enable Webpacker with SplitChunks:

    • Enable SplitChunks with default config by adding to config/webpack/environment.js:

      environment.splitChunks()
    • Enable Webpacker by updating app/views/layouts/application.html.erb:

      Change:

      <%= stylesheet_link_tag 'application', media: 'all' %>
      <%= javascript_pack_tag 'application' %>

      to:

      <%= stylesheet_packs_with_chunks_tag 'application', 'hello_vue', media: 'all' %>
      <%= javascript_packs_with_chunks_tag 'application', 'hello_vue' %>
  2. Verify locally that vue.js is working and SplitChunks is enabled

bin/rails s
open "http://localhost:3000/"

Expect to see

The javascript_packs_with_chunks_tag and stylesheet_packs_with_chunks_tag helpers split assets into small size chunks and create html tags for them:

<script src="/packs/js/runtime~hello_vue-818eba5af0151079cb6c.js"></script>
<script src="/packs/js/1-7b962b4481d6abff6c2b.chunk.js"></script>
<script src="/packs/js/hello_vue-bc0218ac204eff3ff742.chunk.js"></script>

Install Jest for Component Unit Tests

  1. Add Jest with required dependencies
yarn add --dev jest @vue/test-utils vue-jest babel-core@^7.0.0-bridge.0 babel-jest jest-serializer-vue
  1. Configure Jest in package.json (including the Coverage enabling):
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "verbose": true,
    "testURL": "http://localhost/",
    "roots": [
      "test/javascript"
    ],
    "moduleDirectories": [
      "node_modules",
      "app/javascript"
    ],
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/app/javascript/$1"
    },
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transform": {
      ".+\\.js$": "babel-jest",
      ".+\\.vue$": "vue-jest"
    },
    "testPathIgnorePatterns": [
      "<rootDir>/config/webpack/"
    ],
    "snapshotSerializers": [
      "jest-serializer-vue"
    ],
    "collectCoverage": true,
    "collectCoverageFrom": [
      "**/*.{js,vue}",
      "!**/node_modules/**"
    ]
  },
  1. Add test/javascript/test.test.js:
test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});
  1. Verify installation
yarn test

Expect to see

  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.vm).toBeTruthy()
  })

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

You should see all tests passed

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 a Heroku App and provision it

Requirements: Heroku CLI.

NOTE: Do not forget to commit all your changes: git add . && git commit -m "Generates Ruby on Rails application with Vue.js onboard"

heroku create

heroku addons:create heroku-postgresql:hobby-dev

heroku buildpacks:add heroku/ruby

heroku config:set RAILS_ENV=production NODE_ENV=production YARN_PRODUCTION=true MALLOC_ARENA_MAX=2
  1. Setup Node.js for Heroku
heroku buildpacks:add --index 1 heroku/nodejs

Use the engines section of the package.json to specify the version of Node.js to use on Heroku. Drop the โ€˜vโ€™ to save only the version number:

{
  "engines": {
    "node": ">= 12.x"
  }
}
  1. Deploy and verify that vue.js is working on Heroku
git push heroku master

heroku apps:open

Setup basic PWA

  1. Install serviceworker-rails by adding into Gemfile:
gem 'serviceworker-rails', github: 'rossta/serviceworker-rails'
  1. Following the guide: https://github.com/rossta/serviceworker-rails you should get something like: https://gist.github.com/pftg/786b147eff85a6fc98bd8dc1c3c9778e

  2. There'll be an issue with service worker registration on the page saying: Uncaught ReferenceError: window is not defined and Failed to register a ServiceWorker.... To fix that add following line to config/webpack/environment.js as suggested here:

environment.config.set('output.globalObject', 'this')

Setup Turbolinks

  1. Add node dependencies
yarn add vue-turbolinks turbolinks
  1. Load Turbolinks by adding to app/javascript/initializers/turbolinks.js:
import Turbolinks from 'turbolinks'
Turbolinks.start()
  1. Add to app/javascript/packs/application.js:
import 'initializers/turbolinks.js'
  1. Change app/javascript/packs/hello_vue.js to:
import TurbolinksAdapter from 'vue-turbolinks'
import Vue from 'vue'
import App from '../app.vue'

Vue.use(TurbolinksAdapter)

document.addEventListener('turbolinks:load', () => {
  const app = new Vue({
    render: h => h(App),
    el: '#hello_vue_app'
  }).$mount()
})
  1. Update layout app/views/layouts/application.html.erb:
<%= javascript_packs_with_chunks_tag 'hello_vue', 'application', 'data-turbolinks-track': 'reload' %>
  1. Run tests and server to verify:
bin/rails t
bin/rails s

Setup AdminLTE

  1. Add node dependencies
yarn add admin-lte bootstrap jquery popover @fortawesome/fontawesome-free
  1. Add app/javascript/initializers/adminlte.js initializer:
import '../assets/adminlte.scss'
import('./plugins') // () needed for async loading
  1. Add app/javascript/initializers/plugins.js file with plugin importing:
import '@fortawesome/fontawesome-free'
import 'jquery/src/jquery.js'
import 'popper.js'
import 'bootstrap'
import 'admin-lte/build/js/AdminLTE'
  1. Import admin lte initializer in app/javascript/packs/application.js pack:
import 'initializers/adminlte'
  1. Next step is updating main layout app/views/layouts/application.html.erb. Code for layout you can find here. Also don't forget to add yield in div with content class:
<div class="content">
    <%= yield %>
</div>
  1. Add styles to app/javascript/assets/adminlte.scss:
$fa-font-path: '~@fortawesome/fontawesome-free/webfonts';

@import '~@fortawesome/fontawesome-free/scss/fontawesome';
@import '~@fortawesome/fontawesome-free/scss/solid';
@import '~@fortawesome/fontawesome-free/scss/regular';
@import '~@fortawesome/fontawesome-free/scss/brands';

@import "~admin-lte/build/scss/adminlte";
  1. Run tests and server to verify:
yarn test
bin/rails test
bin/rails test:system
bin/rails s

Expect to see: image

Configure continuous integration and other services for static code analysis.

To be able to automatically analyze the quality of the code, let's install the jt_tools gem.

  1. Add this line to your application's Gemfile:
gem 'jt_tools', groups: [:development]
  1. Next step is running bundle install and generator:
bin/bundle
bin/rails jt_tools:install
  1. Run linters to verify
bin/lint-pr

You should see a list of the linters that were running.

vuejs-rails-starterkit's People

Contributors

dependabot[bot] avatar miry avatar pftg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vuejs-rails-starterkit's Issues

Your .dependabot/config.yml contained invalid details

Dependabot encountered the following error when parsing your .dependabot/config.yml:

The property '#/' did not contain a required property of 'update_configs'
The property '#/' contains additional properties ["updates"] outside of the schema when none are allowed
The property '#/version' value 2 did not match one of the following values: 1

Please update the config file to conform with Dependabot's specification using our docs and online validator.

Can this work as a PWA?

I just started learning PWAs. Can this work with a Vue-based service worker vue init pwa or a Rails-based serviceworker gem "serviceworker-rails" ?

Update script with missed steps: upgrade webpacker and babel

  1. Run bin/rails db:migrate to generate schema

  2. Update bin/setup & bin/update:

  # Install JavaScript dependencies if using Yarn
  system('bin/yarn')
  1. Update webpacker yarn to: yarn add @rails/webpacker@next
  2. Replace .babelrc with https://github.com/rails/webpacker/blob/master/lib/install/config/.babelrc
  3. Replace .postcss.yml with https://github.com/rails/webpacker/blob/master/lib/install/config/.postcssrc.yml
  4. test assets compilation: bin/webpack
  5. Fix path: app/views/layouts/application.html.erb
  6. Generator use Landing controller instead Home
  7. do not raun rails s after new controller
  8. Use yarn add @vue/babel-preset-app
"presets": [
  3     [
  4     "@vue/app",
  5       {
  6         "modules": false,
  7         "forceAllTransforms": true,
  8         "useBuiltIns": "entry"
  9       }
 10     ]
 11   ],
  1. jest:
+  "env": {
+  14     "test": {
+  15       "presets": [
+  16         ["@babel/preset-env", {
+  17           "targets": {
+  18             "node": "current"
+  19           }
+  20       }]]
+  21   }},
  1. yarn add --dev jest vue-jest @vue/test-utils jest-serializer-vue babel-jest 'babel-core@^7.0.0-bridge' @babel/core

Your .dependabot/config.yml contained invalid details

Dependabot encountered the following error when parsing your .dependabot/config.yml:

The property '#/update_configs/0/version_requirement_updates' value "off -" did not match one of the following values: off, auto, widen_ranges, increase_versions, increase_versions_if_necessary
The property '#/update_configs/1/version_requirement_updates' of type boolean did not match the following type: string
The property '#/update_configs/1/version_requirement_updates' value false did not match one of the following values: off, auto, increase_versions, increase_versions_if_necessary

Please update the config file to conform with Dependabot's specification using our docs and online validator.

Error in step: Install Jest for Component Unit Tests

no matches found: babel-core@^7.0.0-bridge.0

From what I could google there seems to be some naming issues with Babel 7, but I'm not sure what the solution is. I tried babel-core@^7.0.0-0 as suggested elsewhere, but that didn't work either. Does command suggested here work for anyone?

How to enable lang=postcss?

If I change app.vue's <style> section to choose lang=postcss I get an error when I refresh the home page:

Failed to compile.

./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&lang=postcss&scoped=true& (./node_modules/vue-loader/lib??vue-loader-options!./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&lang=postcss&scoped=true&) 18:2
Module parse failed: Unexpected token (18:2)
File was processed with these loaders:
 * ./node_modules/vue-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| 
| 
> p {
|   font-size: 2em;
|   text-align: center;

All I did was set the lang in app.vue:

<style lang="postcss" scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

Turbolinks intergration

I find that in order for the hello_vue example to work as expected with turbolinks, i have to import
import "initializers/turbolinks.js"
In hello_vue.js and not application.js.
or i load
<%= javascript_pack_tag 'application' %>
from application.html.erb
I wonder why

Add simple example for Hybrid Vuejs Usage

We need to show some simple examples for what case we would have Hybrid Vue.js.

Need to research what is the best example

  • Trello Like Board
  • Sign in/up form in modal
  • Chat
  • TODO MVC
  • Show last Medium Articles from https://jtway.co
  • Show last GitHub Commits

Setup CSP

I'm building a Rails app with Vuetify, too - and have trouble setting up CSP (content security policy) with Vuetify theming. I would like to see how you are doing this.

In the Vuetify docs using a nonce for CSP is recommended:
https://vuetifyjs.com/en/style/theme#introduction

I have tried it without success, the generated theme always has an empty nonce. Here is my code:

config/initializers/content_security_policy.rb:

Rails.application.config.content_security_policy do |policy|
  if Rails.env.development?
    policy.script_src :self, :https, :unsafe_eval
    policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035'
  else
    policy.default_src :self, :https
    policy.font_src    :self, :https, :data
    policy.img_src     :self, :https, :data
    policy.object_src  :none
    policy.script_src  :self, :https
    policy.style_src   :self, :https
  end

  # Specify URI for violation reports
  # policy.report_uri "/csp-violation-report-endpoint"
end

# If you are using UJS then enable automatic nonce generation
Rails.application.config.content_security_policy_nonce_generator = ->(_request) { SecureRandom.base64(16) }

app/javascript/packs/application.js:

import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import 'vuetify/src/stylus/app.styl'

const railsNonce = document.querySelector('meta[name=csp-nonce]').getAttribute('content')

Vue.use(Vuetify, {
  options: {
    cspNonce: railsNonce,
  },
})

Optimize entrypoint sizes

remote:        WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
remote:        This can impact web performance.
remote:        Assets:
remote:          media/webfonts/fa-solid-900-0724bb8b.svg (829 KiB)
remote:          media/webfonts/fa-brands-400-9d67fa14.svg (699 KiB)
remote:          css/application~dfc1eb77-d108fc03.chunk.css (670 KiB)
remote:
remote:        WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
remote:        Entrypoints:
remote:          application (1.38 MiB)

Setup Browser Tests

We should add some examples of Capybara tests with js enabled in order to verify integration of client side and server side code

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.