Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save monogot/32635f99ab7c51c3b46aa16f1fd14d56 to your computer and use it in GitHub Desktop.
Save monogot/32635f99ab7c51c3b46aa16f1fd14d56 to your computer and use it in GitHub Desktop.
Rails 5.2 with webpacker, bootstrap, stimulus starter

Rails 5.2 with webpacker, bootstrap, stimulus starter

This gist will collect all issues we solved with Rails 5.2 and Webpacker

Create Project

# Last few parameters(--skip-* part) is only my habbit not actully required
$ rails new <project_name> --webpack=stimulus --database=postgresql --skip-coffee --skip-test
$ cd <project_name>
$ rails db:create

Configure scss architecture

If you are using some front end framework you may like to integrate stylesheet into components with webpack or you just like to integrate stylesheets with webapck like me. This is a way that we integrate that into webpacker.

NOTE: This is only the convention of our team you can avoid this step and keep stylesheet in assets/.

$ mkdir app/javascript/stylesheets
$ touch app/javascript/stylesheets/application.scss
$ touch app/javascript/stylesheets/_variables.scss
$ touch app/javascript/stylesheets/_base.scss

After create files please write down styles as follow:

app/javascript/stylesheets/application.scss

@import 'variables';
@import 'base';

app/javascript/stylesheets/_variables.scss

$colors: (
  major: #00D252,
  minor: #2F3B59
);

app/javascript/stylesheets/_base.scss

h1 {
  color: map-get($colors, major);
}

On the top of app/javascript/packs/application.js

import 'stylesheets/application'

(Optional)Integrate stimulus manually

If you are not use --webpack=stimulus for create project or install stimulus in existed project.

$ yarn add stimulus
$ mkdir app/javascript/controllers
# To provide a example for testing stimulus
$ touch app/javascript/controllers/clipboard_controller.js

(Optional)Configure stimulus

app/javascript/s/packs/application.js

/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
import 'stylesheets/application'

import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"

const application = Application.start()
// The path you may like to change to under `pack` that path will be `./controllers`
// but convention will be in `/app/javascript/controllers`
const context = require.context("controllers", true, /\.js$/)
application.load(definitionsFromContext(context))

Example of testing stimulus:

app/javascript/controllers/clipboard_controller.js

import { Controller } from 'stimulus'

export default class extends Controller {
  static targets = ['source']
  initialize() {
    console.log('clipboard initialize')
  }
  connect() {
    console.log('clipboard connect')
    if (document.queryCommandSupported('copy')) {
      this.element.classList.add('clipboard--supported')
    }
  }
  copy(e) {
    e.preventDefault()
    this.sourceTarget.select()
    document.execCommand('copy')
  }
}

Create a example controller and view

$ rails g controller pages example

Add app/views/pages/example.html.erb

<h1>Hello, World</h1>
<hr>
<div data-controller="clipboard members dashboard">
  PIN
  <input type="text" data-target="clipboard.source" value="1234" readonly>
  <button data-action="clipboard#copy" class="clipboard-button">
    Copy to Clipboard
  </button>
</div>

Add pack to layout

Open app/views/layout/application.html.erb then add pack tags to <head>

<%= stylesheet_pack_tag 'application' %>
<%= javascript_pack_tag 'application' %>

Add route

config/routes.rb

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root 'pages#example'
end

Then you can test

$ rails s

Navigate to localhost:3000 should see as follow

Until here you should complete Rails 5.2 using webpacker with stimulus and stylesheets.

For common practical stiuation you may want to use bootstrap v4.x.

Install bootstrap

# https://getbootstrap.com/docs/4.1/getting-started/webpack/
$ yarn add jquery popper.js bootstrap

Import boostrap stylesheets

In app/javascript/stylesheets/application.scss add bootstrap

@import '~bootstrap/scss/bootstrap';
@import 'variables';
@import 'base';

imiport bootstrap JavaScript

app/javascript/packs/application.js

import 'bootstrap'

Configure webpacker

Add configuration to config/webpack/environment.js. If you do not setup this step, the abilities related to Popper.js such as tooltip will not working.

const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
/**
 * Automatically load modules instead of having to import or require them everywhere.
 * Support by webpack. To get more information:
 *
 * https://webpack.js.org/plugins/provide-plugin/
 * http://j.mp/2JzG1Dm
 */
environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    jquery: 'jquery',
    'window.jQuery': 'jquery',
    Popper: ['popper.js', 'default']
  })
)
module.exports = environment

Sometimes you may like to use jQuery in views you should expose jQuery to global

expose jQuery to global for views

# https://webpack.js.org/loaders/expose-loader/
$ yarn add expose-loader -D

Add configuration to config/webpack/environment.js

/**
 * To use jQuery in views
 */
environment.loaders.append('expose', {
  test: require.resolve('jquery'),
  use: [{
    loader: 'expose-loader',
    options: '$'
  }]
})

Other convention of our team

$ mkdir -p lib/templates/active_record/model
$ touch lib/templates/active_record/model/model.rb

lib/templates/active_record/model/model.rb

<% module_namespacing do -%>
class <%= class_name %> < <%= parent_class_name.classify %>
  # scope macros

  # Concerns macros

  # Constants

  # Attributes related macros
<% if attributes.any?(&:password_digest?) -%>
  has_secure_password
<% end -%>

  # association macros
<% attributes.select(&:reference?).each do |attribute| -%>
  belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
<% end -%>

  # validation macros

  # callbacks

  # other

  private
    # callback methods
end
<% end -%>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment