Skip to content

Instantly share code, notes, and snippets.

@eoinkelly
Last active February 1, 2016 21:50
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eoinkelly/5778004 to your computer and use it in GitHub Desktop.
Save eoinkelly/5778004 to your computer and use it in GitHub Desktop.
Getting started with requirejs-rails

Usage

  1. Add this to your Rails app's Gemfile:

    gem 'requirejs-rails'
    

    and then run bundle install on the command line.

  2. Use requirejs_include_tag at the top-level of your app's layout(s). Other modules will be pulled in dynamically by require.js in development and for production builds optimized by r.js. Here's a basic app/views/layouts/application.html.erb modified for requirejs-rails:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Frobnitz Online</title>
      <%= stylesheet_link_tag   "application" %>
      <%= requirejs_include_tag "application" %>
      <%= csrf_meta_tags %>
      <meta charset="utf-8">
    </head>
    <body>
    
    <%= yield %>
    
    </body>
    </html>
  3. Remove all Sprockets directives such as //= require jquery from application.js and elsewhere. Instead establish JavaScript dependencies using AMD-style define() and require() calls.

    // app/assets/javascripts/application.js
    
    require(['jquery'], function($) {
      'use strict';
    
      // Your awesome javascript goes here!
    
      // **********************************
      // This is just some guff to help you prove that everything works. 
      // You can and should delete this once everything works.
      console.log('Successfully loaded jQuery version: ' + $('body').jquery);
      if (typeof $.rails === 'object') {
        console.log('The $ object seems to have been decorated by Rails UJS successfully. Good job!');
      }
      else {
        console.log('Uh-oh, it seems that $ has not been decorated by Rails UJS. You might want to check this.');
      }
      // **********************************
    
    });

    or if you prefer the coffeescript flavor use:

    # app/assets/javascripts/application.js.coffee
    
    require ['jquery'], ($) ->
    
      # Your awesome coffeescript goes here!
    
      # **************************************
      # This is just some guff to help you prove that everything works. 
      # You can and should delete this once everything works.
      # **************************************
      console.log 'Loaded jQuery version: ' + $('body').jquery 
      if $.rails?
        console.log 'The $ object seems to have been decorated by Rails UJS successfully. Good job!'
      else
        console.log 'Uh-oh, it seems that $ has not been decorated by Rails UJS. You might want to check this.'
      # **************************************
  4. Create config/requirejs.yml with the following content:

    # This file contains the requirejs config in YAML format.  
    # RequireJS Config: http://requirejs.org/docs/api.html#config 
    # YAML Docs:        http://www.yaml.org
    shim:
      # tell requirejs that jquery_ujs (Rails' built-in JS) depends on jQuery
      'jquery_ujs': 
        - 'jquery' 
    
    # Setup a mapping so that any JS module in the system that asks for jQuery will
    # automatically get jQuery with Rails' unobtrusive JS customisations applied.
    
    # Any module that does require('jquery') will actually get
    # jquery-with-rails-ujs.js instead. We also make an exception for jquery_ujs.js
    # and jquery-with-rails-ujs.js themselves - they need to get the real jQuery.
    map:
      '*':
        'jquery': 'jquery-with-rails-ujs'
      'jquery_ujs': 
        'jquery': 'jquery' 
      'jquery-with-rails-ujs': 
        'jquery': 'jquery' 

    VERY IMPORTANT: Don't forget to restart your rails server if you have one running or it won't see any changes in here! You will have to restart your rails server every time you change this file! It seems that requirejs will crash if config/requirejs.yml exists but does not have any content (comments don't count) so watch out for that too.

  5. Setup Rails Unobtrusive Javascript

    Rails unobtrusive javascript jquery_ujs.js decorates the jQuery object ($) with some helpers. We want those helpers to be available for all our modules so we create a module called jquery-with-rails-ujs.js. This cunningly named module depends on both jquery and jquery_ujs and simply returns the $ object. This has the desired side-effect of ensuring that the $ object we get back is always decorated by Rails' unobtrusive javascript.

    Create a new file:

    // app/assets/javascripts/jquery-with-rails-ujs.js
    
    define(['jquery', 'jquery_ujs'], function ($) {
      'use strict';
      // By depending on jQuery and Rails' built-in unobtrusive Javascript we
      // ensure that the jQuery object we return has Rails' customisations applied.
      return $;
    });

    and again if you prefer coffeescript, use this instead:

    # app/assets/javascripts/jquery-with-rails-ujs.js.coffee
    
    define ['jquery', 'jquery_ujs'], ($) ->
    
      # By depending on jQuery and Rails' built-in unobtrusive Javascript we
      # ensure that the jQuery object we return has Rails' customisations applied.
      return $
  6. Check that it all worked

    There is some debugging output in app/assets/javascripts/application.js (or app/assets/javascripts/application.js.coffee. Open the javascript console in your browser to view it.

    You should remove that debugging output when everything is working - remember some older browsers don't have a console object so calls to console.log will cause the browser to stop evaluating javascript.

    Any modules you add to your application now that specify jquery as a dependency will automatically get the rails decorated version. Default rails functionality that relies on unobtrusive JS e.g. submitting requests using HTTP methods other than GET/POST should also just work.

  7. When ready, build your assets for production deployment as usual. requirejs-rails defaults to a single-file build of application.js. Additional modules and r.js layered builds may be specified via config/requirejs.yml; see the Configuration section below.

    rake assets:precompile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment