diff --git a/Gemfile b/Gemfile index b77cf4f..a08c24e 100644 --- a/Gemfile +++ b/Gemfile @@ -55,3 +55,5 @@ end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +gem 'mini_racer', platforms: :ruby \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 4eceb93..d351168 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,6 +81,7 @@ GEM jbuilder (2.7.0) activesupport (>= 4.2.0) multi_json (>= 1.2) + libv8 (5.9.211.38.1-x86_64-darwin-16) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -95,6 +96,8 @@ GEM mime-types-data (3.2016.0521) mini_mime (0.1.4) mini_portile2 (2.2.0) + mini_racer (0.1.14) + libv8 (~> 5.9) minitest (5.10.3) multi_json (1.12.1) nio4r (2.1.0) @@ -199,6 +202,7 @@ DEPENDENCIES coffee-rails (~> 4.2) jbuilder (~> 2.5) listen (>= 3.0.5, < 3.2) + mini_racer puma (~> 3.7) rails (~> 5.1.3) react_on_rails! diff --git a/Procfile.dev b/Procfile.dev new file mode 100644 index 0000000..8af6663 --- /dev/null +++ b/Procfile.dev @@ -0,0 +1,4 @@ +web: rails s -p 3000 + +# Next line runs a watch process with webpack +client: sh -c 'rm -rf public/packs/* || true && bundle exec rake react_on_rails:locale && bin/webpack -w' diff --git a/Procfile.dev-server b/Procfile.dev-server new file mode 100644 index 0000000..038d37a --- /dev/null +++ b/Procfile.dev-server @@ -0,0 +1,5 @@ +web: rails s -p 3000 + +# Next line runs the webpack-dev-server +# You can edit config/webpacker.yml to set HMR to true to see hot reloading +client: sh -c 'rm -rf public/packs/* || true && bundle exec rake react_on_rails:locale && bin/webpack-dev-server' diff --git a/app/controllers/hello_world_controller.rb b/app/controllers/hello_world_controller.rb new file mode 100644 index 0000000..ad09c5e --- /dev/null +++ b/app/controllers/hello_world_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class HelloWorldController < ApplicationController + layout "hello_world" + + def index + @hello_world_props = { name: "Stranger" } + end +end diff --git a/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx b/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx new file mode 100644 index 0000000..726e1c8 --- /dev/null +++ b/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx @@ -0,0 +1,45 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +export default class HelloWorld extends React.Component { + static propTypes = { + name: PropTypes.string.isRequired, // this is passed from the Rails view + }; + + /** + * @param props - Comes from your rails view. + */ + constructor(props) { + super(props); + + // How to set initial state in ES6 class syntax + // https://facebook.github.io/react/docs/reusable-components.html#es6-classes + this.state = { name: this.props.name }; + } + + updateName = (name) => { + this.setState({ name }); + }; + + render() { + return ( +
+

+ Hello, {this.state.name}! +

+
+
+ + this.updateName(e.target.value)} + /> +
+
+ ); + } +} diff --git a/app/javascript/packs/hello-world-bundle.js b/app/javascript/packs/hello-world-bundle.js new file mode 100644 index 0000000..9b80e86 --- /dev/null +++ b/app/javascript/packs/hello-world-bundle.js @@ -0,0 +1,8 @@ +import ReactOnRails from 'react-on-rails'; + +import HelloWorld from '../bundles/HelloWorld/components/HelloWorld'; + +// This is how react_on_rails can see the HelloWorld in the browser. +ReactOnRails.register({ + HelloWorld, +}); diff --git a/app/views/hello_world/index.html.erb b/app/views/hello_world/index.html.erb new file mode 100644 index 0000000..396d0a5 --- /dev/null +++ b/app/views/hello_world/index.html.erb @@ -0,0 +1,2 @@ +

Hello World

+<%= react_component("HelloWorld", props: @hello_world_props, prerender: false) %> diff --git a/app/views/layouts/hello_world.html.erb b/app/views/layouts/hello_world.html.erb new file mode 100644 index 0000000..d9c08f9 --- /dev/null +++ b/app/views/layouts/hello_world.html.erb @@ -0,0 +1,12 @@ + + + + ReactOnRailsWithWebpacker + <%= csrf_meta_tags %> + <%= javascript_pack_tag 'hello-world-bundle' %> + + + + <%= yield %> + + diff --git a/config/initializers/react_on_rails.rb b/config/initializers/react_on_rails.rb new file mode 100644 index 0000000..013728c --- /dev/null +++ b/config/initializers/react_on_rails.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# See docs/basics/configuration.md for many more options + +ReactOnRails.configure do |config| + # This configures the script to run to build the production assets by webpack. Set this to nil + # if you don't want react_on_rails building this file for you. + config.npm_build_production_command = "RAILS_ENV=production bin/webpack" + + ################################################################################ + ################################################################################ + # TEST CONFIGURATION OPTIONS + # Below options are used with the use of this test helper: + # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) + ################################################################################ + + # If you are using this in your spec_helper.rb (or rails_helper.rb): + # + # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) + # + # with rspec then this controls what yarn command is run + # to automatically refresh your webpack assets on every test run. + # + config.build_test_command = "RAILS_ENV=test bin/webpack" + + ################################################################################ + ################################################################################ + # SERVER RENDERING OPTIONS + ################################################################################ + # This is the file used for server rendering of React when using `(prerender: true)` + # If you are never using server rendering, you should set this to "". + # Note, there is only one server bundle, unlike JavaScript where you want to minimize the size + # of the JS sent to the client. For the server rendering, React on Rails creates a pool of + # JavaScript execution instances which should handle any component requested. + # + # While you may configure this to be the same as your client bundle file, this file is typically + # different. You should have ONE server bundle which can create all of your server rendered + # React components. + # + config.server_bundle_js_file = "hello-world-bundle.js" +end diff --git a/config/routes.rb b/config/routes.rb index 787824f..bbdd490 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ Rails.application.routes.draw do + get 'hello_world', to: 'hello_world#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end diff --git a/package.json b/package.json index c7556b0..0178780 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "babel-preset-react": "^6.24.1", "prop-types": "^15.5.10", "react": "^15.6.1", - "react-dom": "^15.6.1" + "react-dom": "^15.6.1", + "react-on-rails": "^9.0.0-beta.11" }, "devDependencies": { "webpack-dev-server": "^2.7.1" diff --git a/yarn.lock b/yarn.lock index 544305d..3421209 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4172,6 +4172,10 @@ react-dom@^15.6.1: object-assign "^4.1.0" prop-types "^15.5.10" +react-on-rails@^9.0.0-beta.11: + version "9.0.0-beta.11" + resolved "https://registry.yarnpkg.com/react-on-rails/-/react-on-rails-9.0.0-beta.11.tgz#f6951129d7c2a67479281ca900859d5ac0aab978" + react@^15.6.1: version "15.6.1" resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"