| title |
|---|
Installation |
There are several ways to install Hyperloop into your development environment.
- Experimenting online in the Opal playground
- Running exclusively in your browser with Hyperloop Express
- Integrating with the Rails Asset Pipeline
- Building a single
application.jswith Rake - Using NPM and Webpack to require all your JavaScript components
A great way to start learning HyperReact is use OpalPlayground.
Here is a simple HelloWorld example to get you started.
For small static sites that don't need a server backend you can use the reactrb-express javascript library. Simply include the reactrb-express.js file with your other javascript code, or access it directly via the CDN, and you are good to go.
This is another great way to experiment with HyperReact. You don't need any setup or download to get started.
HyperReact works great with new or existing rails apps, and HyperReact plays well with other frameworks, so it's pain free to introduce React to your application.
We recommend you use the HyperRails gem to do a transparent install of everything you need in a new or existing rails app.
In your Gemfile
gem "hyper-rails"then
bundle install
rails g hyperloop:install
bundle updateIf you need any help with your installation please contact us on gitter.im
Within a Rails app React Components are by convention stored in the app/views/components directory.
Your Rails controllers, and layouts access your top level components using the render_component method.
During server-side-rendering your components will be called on to generate the resulting HTML just like ERB or HAML templates. The resulting HTML is delivered to the client like any other rails view, but in addition all the code needed to keep the component dynamically updating is delivered as well. So now as events occur on the client the code is re-rendered client side with no server action required.
Because React plays well with others, you can start with a single aspect of a page or layout (a dynamic chat widget for example) and add a React component to implement that functionality.
Once you are setup (i.e. rails g hyperloop:install) components may be rendered directly from a controller action by simply following a naming convention.
To render a component from the home#show action, create a component class named Show. Note: You can use the rails g hyperloop:component Home::Show command to generate a component template.
# app/views/components/home/show.rb
module Components
module Home
class Show < React::Component::Base
param :say_hello_to
def render
puts "Rendering my first component!"
"hello #{params.say_hello_to if params.say_hello_to}"
end
end
end
endTo render the component call render_component in the controller action passing along any params:
# controllers/home_controller.rb
class HomeController < ApplicationController
def show
# render_component uses the controller name to find the 'show' component.
render_component say_hello_to: params[:say_hello_to]
end
endOr from a view:
<%= react_component('Home::Show', say_hello_to: "Sally") %>Make sure your routes file has a route to your home#show action. Visit that route in your browser and you should see 'Hello' rendered.
Open up the js console in the browser and you will see a log showing what went on during rendering.
Have a look at the sources in the console, and notice your ruby code is there, and you can set break points etc.
The following can easily be achieved by using the generators in hyper-rails gem but the steps are simple if you prefer to do them yourself.
To start using HyperReact within a new or existing Rails 4.x or Rails 5.x app, follow these steps:
In your Gemfile:
# Gemfile
gem 'opal-rails'
gem 'opal-browser'
gem 'hyper-react'
gem 'therubyracer', platforms: :ruby
gem 'react-router-rails', '~> 0.13.3'
gem 'hyper-router'
gem 'hyper-mesh'Run bundle install and restart your rails server.
Your react components will go into the app/views/components/ directory of your rails app.
Within your app/views directory you need to create a components.rb manifest.
Files required in app/views/components.rb will be made available to the server side rendering system as well as the browser.
# app/views/components.rb
require 'opal'
require 'react/react-source'
require 'hyper-react'
if React::IsomorphicHelpers.on_opal_client?
require 'opal-jquery'
require 'browser'
require 'browser/interval'
require 'browser/delay'
# add any additional requires that can ONLY run on client here
end
require 'hyper-router'
require 'react_router'
require 'hyper-mesh'
require 'models'
require_tree './components'Typically the client will need all the above assets, plus other files that are client only. Notably jQuery is a client only asset.
NOTE: You can update your existing application.js file, or convert it to ruby syntax and name it application.rb. The example below assumes you are using ruby syntax. However if you are using application.js then use the standard //= require '...' format and load your components with Opal.load('components');
Assuming you are using the ruby syntax (application.rb), in assets/javascript/application.rb require your components manifest as well as any additional browser only assets.
# assets/javascript/application.rb
# Add React and make components available by requiring your components.rb manifest.
require 'react/react-source'
require 'components'
# 'react_ujs' tells react in the browser to mount rendered components.
require 'react_ujs'
# Require your other javascript assets. jQuery for example...
require 'jquery' # You need both these files to access jQuery from Opal.
require 'opal-jquery' # They must be in this order.
require 'opal-browser'
# Finally have Opal load your components.rb
Opal.load('components')Finally you will need to update your application.rb to ensure everything works in production:
config.eager_load_paths += %W(#{config.root}/app/models/public)
config.eager_load_paths += %W(#{config.root}/app/views/components)
config.autoload_paths += %W(#{config.root}/app/models/public)
config.autoload_paths += %W(#{config.root}/app/views/components)
config.assets.paths << ::Rails.root.join('app', 'models').to_sThere are two ways to render a component - either directly from a controller or from a view. If you opt to render a component from a controller, pre-rendering is done by default, but if you opt to render the component via a view then pre-rendering is not done by default. There are limitations to pre-rendering (for example you cannot use JQuery) so it is up to you to decide which approach you prefer.
# controllers/home_controller.rb
class HomeController < ApplicationController
def show
# render_component uses the controller name to find the 'show' component.
render_component say_hello_to: params[:say_hello_to]
end
def index
# or just simply with no params
render_component
end# views/home/show.html.erb
<%= react_component('Home::Show', say_hello_to: params[:say_hello_to]) %>HyperReact works fine with Sinatra. Use this Sinatra Example App to get started.
You can also build a simple front end application with no back end consisting of one JS file, one CSS file and and index.html.
In the example below we will build a simple app.js file from a Hyper-react components using Opal.
Add the following gems, and run bundle install.
# Gemfile
gem 'opal'
gem 'opal-browser' # optional
gem 'hyper-react'
gem 'opal-jquery' # optionalYour rake file task will look like this:
#rake.rb
require 'opal'
require 'hyper-react'
desc "Build app.js"
task :build do
Opal.append_path "react_lib"
File.open("app.js", "w+") do |out|
out << Opal::Builder.build("application").to_s
end
endYour main application.rb file will look like this:
#react_lib/application.rb
require 'opal'
require 'browser/interval' # optional
require 'browser/delay' # optional
# you can pull in the jQuery.js file here, or separately
# but in must be loaded BEFORE opal-jquery
require 'opal-jquery' # optional
require 'react/react-source'
require 'hyper-react'
# here you can require other files, do a require_tree, or
# just add some components inline right here...
class Clock < React::Component::Base
def render
"Hello there - Its #{Time.now}"
end
end
Document.ready? do
Element['#content'].render{ Clock() }
endRun bundle exec rake build
This should build app.js which can be included in your main html file.
Your index.html will look like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
<link rel="stylesheet" href="styles.css">
<script src="app.js"></script>
</head>
<body>
<div id="content"></div>
</body>
</html>Two things to note about the code above:
<meta charset="UTF-8">is important as this is required by Opal<div id="content"></div>is where our Clock component will be rendered fromElement['#content'].render{ Clock() }
As a final note, the resulting JS file may be a little large, so you might want to Gzip or uglify it.
There are a few deployment specific considerations:
- The resulting compiled JavaScript files can be quite large, so you might want to add a minimise, uglify or gzip step
- Some free deployment PaaS (Heroku for example) include low levels of memory and system resources. HyperReact may be configured in such a way that it is pre-rendering all pages before they are delivered to the browser and this can be an issue to the PaaS in a low memory environment. If the server is constrained it is better to turn pre-rendering off.
There is a most excellent Tutorial written by Frederic ZINGG which takes you through a step by step guid to deploying on Heroku.
Check out the tutorials to learn more.
Good luck, and welcome!