Giter VIP home page Giter VIP logo

shakacode / react-webpack-rails-tutorial Goto Github PK

View Code? Open in Web Editor NEW
1.7K 1.7K 383.0 9.01 MB

Example of integration of Rails, react, redux, using the react_on_rails gem, webpack, enabling the es7 and jsx transpilers, and node integration. And React Native! Live Demo:

Home Page: http://www.reactrails.com

License: MIT License

JavaScript 37.14% Ruby 42.62% HTML 8.74% Shell 0.67% SCSS 0.56% Procfile 0.02% Dockerfile 1.36% CSS 0.17% ReScript 8.72%
rails-gem rails-react rails-server react shakacode webpack webpack-server webpack2

react-webpack-rails-tutorial's Introduction

Code Climate Coverage Status

React, Redux, Tailwind CSS, ES7, Webpack, Ruby on Rails Demo

Control Plane Deployment Example

Control Plane offers a viable, cost-saving alternative to Heroku, especially when using the cpl gem to deploy to Control Plane.

ShakaCode recently migrated HiChee.com to Control Plane, resulting in a two-thirds reduction in server hosting costs!

See doc in ./.controlplane/readme.md for how to easily deploy this app to Control Plane.

The instructions leverage the cpl CLI, with source code and many more tips on how to migrate from Heroku to Control Plane in https://github.com/shakacode/heroku-to-control-plane.


React on Rails Pro and ShakaCode Pro Support

React on Rails Pro provides Node server rendering and other performance enhancements for React on Rails.

2018-09-11_10-31-11

For more information, see the React on Rails Pro Docs.

  • Optimizing your front end setup with Webpack v5+ and Shakapacker for React on Rails including code splitting with loadable-components.
  • Upgrading your app to use the current Webpack setup that skips the Sprockets asset pipeline.
  • Better performance client and server side.

ShakaCode can also help you with your custom software development needs. We specialize in marketplace and e-commerce applications that utilize both Rails and React. We can even leverage our code for HiChee.com for your app!

See the ShakaCode Client Engagement Model article to learn how we can work together.


Community


Testimonials

From Joel Hooks, Co-Founder, Chief Nerd at egghead.io, January 30, 2017:

2017-01-30_11-33-59

For more testimonials, see Live Projects and Kudos.


Videos

  1. History and Motivation
  2. Basic Tutorial Walkthrough
  3. Code Walkthrough

NEWS

You can see this tutorial live here: http://reactrails.com/

Table of Contents

Demoed Functionality

  • Example of using the react_on_rails gem for easy react/webpack integration with Rails.
  • Example of React with CSS Modules inside of Rails using Webpack as described in Smarter CSS builds with Webpack.
  • Example of enabling hot reloading of both JS and CSS (modules) from your Rails app in development mode. Change your code. Save. Browser updates without a refresh!
  • Example of React/Redux with Rails Action Cable.
  • Example of Rails 7 with ReactJs/Redux/React-Router with Webpack and ES7.
  • Enabling development of a JS client independently from Rails using the Webpack Dev Server. You can see this by starting the app and visiting http://localhost:4000
  • Enabling the use of npm modules and Babel with a Rails application using Webpack.
  • Easily enable retrofitting such a JS framework into an existing Rails app. You don't need a brand new single page app!
  • Example setting up Ruby and JavaScript linting in a real project, with corresponding CI rake tasks.
  • Enabling the i18n functionality with react-intl.

Technologies involved

See package.json and Gemfile for versions

  1. react_on_rails gem
  2. React
  3. Redux
  4. react-router
  5. react-router-redux
  6. Webpack with hot-reload (for local dev)
  7. Babel transpiler
  8. Ruby on Rails 7 for backend app and comparison with plain HTML
  9. Heroku for Rails 7 deployment
  10. Deployment to the ControlPlane
  11. Turbolinks 5
  12. Tailwind CSS

Basic Demo Setup

Prerequisites

  • Node v18.13.0 or above. Be sure that you have Node installed! We suggest using nvm and running nvm list to check the active Node version. See this article Updating and using nvm.
  • Ruby 3.1.2 or above
  • Postgres v9.2 or above
  • Redis. Check that you have Redis installed by running which redis-server. If missing and on MacOS, install with Homebrew (brew install redis)
  • Yarn.

Setup

  1. git clone [email protected]:shakacode/react-webpack-rails-tutorial.git
  2. cd react-webpack-rails-tutorial
  3. bundle install
  4. yarn
  5. rake db:setup
  6. rails start

Basic Command Line

  • Run all linters and tests: rake
  • See all npm commands: yarn run
  • To start all development processes: foreman start -f Procfile.dev
  • To start only all Rails development processes: foreman start -f Procfile.hot

Rails Integration

We're now using Webpack for all Sass and JavaScript assets so we can do CSS Modules within Rails!

  • Production Deployment: heroku-deployment.md.
    • Configure Buildpacks
      heroku buildpacks:set heroku/ruby --app your-app
      heroku buildpacks:add --index 1 heroku/nodejs --app your-app
      heroku buildpacks:set --index 3 https://github.com/sreid/heroku-buildpack-sourceversion.git --app your-app
      

Testing

  • See Yak Shaving Failing Integration Tests with React and Rails

  • Be sure to see Integration Test Notes for advice on running your integration tests.

  • Testing Mode: When running tests, it is useful to run foreman start -f Procfile.spec in order to have webpack automatically recompile the static bundles. Rspec is configured to automatically check whether or not this process is running. If it is not, it will automatically rebuild the webpack bundle to ensure you are not running tests on stale client code. This is achieved via the ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) line in the rails_helper.rb file. If you are using this project as an example and are not using RSpec, you may want to implement similar logic in your own project.

Webpack

Converted to use Shakapacker webpack configuration.

Additional Resources

Sass, CSS Modules, and Tailwind CSS Integration

This example project uses mainly Tailwind CSS for styling. Besides this, it also demonstrates Sass and CSS modules, particularly for some CSS transitions.

We're using Webpack to handle Sass assets so that we can use CSS modules. The best way to understand how we're handling assets is to close follow this example. We'll be working on more docs soon. If you'd like to give us a hand, that's a great way to learn about this!

For example in client/app/bundles/comments/components/CommentBox/CommentBox.jsx, see how we use standard JavaScript import syntax to refer to class names that come from CSS modules:

import css from './CommentBox.module.scss';

export default class CommentBox extends React.Component {
  render() {
    const { actions, data } = this.props;
    const cssTransitionGroupClassNames = {
      enter: css.elementEnter,
      enterActive: css.elementEnterActive,
      exit: css.elementLeave,
      exitActive: css.elementLeaveActive,
    };
  }
}

Fonts with SASS

The tutorial makes use of a custom font OpenSans-Light. We're doing this to show how to add assets for the CSS processing. The font files are located under client/app/assets/fonts and are loaded by both the Rails asset pipeline and the Webpack HMR server.

Process management during development

bundle exec foreman start -f <Procfile>
  1. Procfile.dev: Starts the Webpack Dev Server and Rails with Hot Reloading.
  2. Procfile.static: Starts the Rails server and generates static assets that are used for tests.

Contributors

The Shaka Code team!, led by Justin Gordon, along with with many others. See contributors.md

RubyMine and WebStorm

Special thanks to JetBrains for their great tools: RubyMine and WebStorm. Some developers of this project use RubyMine at the top level, mostly for Ruby work, and we use WebStorm opened up to the client directory to focus on JSX and Sass files.

Hiring

We're looking for great developers that want to work with Rails + React (and react-native!) with a remote-first, distributed, worldwide team, for our own products, client work, and open source. More info here.


Thank you from Justin Gordon and ShakaCode

Thank you for considering using React on Rails.

Aloha and best wishes from the ShakaCode team!

react-webpack-rails-tutorial's People

Contributors

aaronvb avatar ahangarha avatar alex35mil avatar alexeuler avatar alexkval avatar audionerd avatar bronson avatar brucek avatar dylangrafmyre avatar dzirtusss avatar gscarv13 avatar hussainakram avatar jbhatab avatar josiasds avatar judahmeek avatar justin808 avatar mapreal19 avatar marcusvmsa avatar mbreining avatar plasticlizard avatar reconstructions avatar robwise avatar roxolan avatar samnang avatar szyablitsky avatar thewoolleyman avatar thiagoc7 avatar tmobaird avatar vaukalak avatar yassa-hue 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  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

react-webpack-rails-tutorial's Issues

Add scss-lint

Started using scss-lint on another project. No reason not to include it.

Image path needs to go into the bootstrap loader config file

If you refer to images in the bootstrap-loader files, they are not found because there's no default for the image path.

We need to uncomment this line in

https://github.com/justin808/react-webpack-rails-tutorial/blob/master/webpack/bootstrap-sass.config.js

  // Default for the style loading is to put in your js files
  // styleLoader: "style-loader!css-loader!sass-loader";

And it needs to contain the imagePath like this:

https://github.com/justin808/react-webpack-rails-tutorial/blob/master/webpack/webpack.common.config.js

  module: {
    loaders: [
      { test: /\.scss$/, loader: "style!css!sass?outputStyle=expanded&imagePath=/assets/images"},

Loosen up ruby version requirement?

The ruby version specified in the Gemfile is 2.1.3. I've installed 2.1.3 to get started, however this may be a barrier to potential contributors. Suggestions:

  • Remove the ruby version from Gemfile
  • Use an env var:
ruby ENV['CUSTOM_RUBY_VERSION'] || '2.1.3'
  • Leave as is

Move package.json to inside webpack directory

We can have a top level package.json that loads the /webpack/package.json.

This keeps the top level tidier.

From Heroku support:

I agree - as long as an extra root-level package.json is okay with you, it's probably a better bet to just use the officially supported buildpack. You can trigger sub-installs like this (in package.json):

  "scripts": {
    "postinstall": "cd ./client && npm install && cd ../server && npm install"
   }

Also, I'd love to get your feedback on how that works with the upcoming version of the Node buildpack (codenamed "yoga"):
https://github.com/heroku/heroku-buildpack-nodejs/tree/yoga
If you decide to try it out, please let me know what you think!
Thanks,
Hunter

comments right now accept image tags

Somebody put in this comment at

http://www.reactrails.com/

<div class="comment" data-reactid=".0.0.2.$41"><h2 class="comment-author" data-reactid=".0.0.2.$41.0">123</h2><span data-reactid=".0.0.2.$41.1"><p><img src="" onerror="alert(1)"></p>
</span></div>

@mbreining we need to change the demo so that that HTML tags are stripped. In fact, they might be and this may have been entered on the rails side. In any case, any HTML tags should be escaped before display. @Dgrafmyre you can take a quick look at this as well. Might be fun to fix.

railsreacttutorial

Remove bootstrap-sass-loader in favor of manually loading bootstrap

Bootstrap-sass-loader autoloads bootstrap assets from the module so it isn't exposed at all for rails to pickup. This forces you to use the bootstrap-sass gem in addition to the npm module. If we just manually load all of the bootstrap from the npm module, then we can import that into the rails asset pipeline.

So all said and done you would basically move all of your assets to the client folder, manually setup bootstrap in your client folder, and form a new manifest file with everything in the js side. The rails manifest would turn into just requiring that client manifest and maybe some oddball things like bootstrap-sprockets just for the css.

Are there any gotchas I'm missing?

Help with updating ruby, node, gems, npm

I'm got a full refresh to all dependencies here: #56.

However, I can't get rspec to run:

Add new comment
  add post via horizontal, stacked, or inline form (FAILED - 1)

Failures:

  1) Add new comment  add post via horizontal, stacked, or inline form
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit root_path
          EOFError:
            end of file reached
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/connection.rb:55:in `read_nonblock'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/connection.rb:55:in `read'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/connection.rb:46:in `gets'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/browser.rb:299:in `check'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/browser.rb:211:in `command'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/browser.rb:19:in `visit'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/driver.rb:48:in `visit'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-2.4.4/lib/capybara/session.rb:227:in `visit'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-2.4.4/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
          # ./spec/features/comments_spec.rb:5:in `block (2 levels) in <top (required)>'
          # ./spec/rails_helper.rb:42:in `block (3 levels) in <top (required)>'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/generic/base.rb:15:in `cleaning'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/base.rb:92:in `cleaning'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `call'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `cleaning'
          # ./spec/rails_helper.rb:41:in `block (2 levels) in <top (required)>'

     1.2) Failure/Error: Unable to find matching line from backtrace
          Capybara::Webkit::CrashError:
            The webkit_server process crashed!

              Broken pipe

            This is a bug in capybara-webkit. For help with this crash, please visit:

            https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/browser.rb:215:in `rescue in command'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/browser.rb:205:in `command'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/browser.rb:79:in `current_url'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-webkit-1.6.0/lib/capybara/webkit/driver.rb:44:in `current_url'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-2.4.4/lib/capybara/session.rb:175:in `current_url'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-screenshot-1.0.11/lib/capybara-screenshot/rspec.rb:53:in `block in after_failed_example'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-2.4.4/lib/capybara.rb:277:in `using_session'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-screenshot-1.0.11/lib/capybara-screenshot/rspec.rb:52:in `after_failed_example'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/capybara-screenshot-1.0.11/lib/capybara-screenshot/rspec.rb:82:in `block (2 levels) in <top (required)>'
          # ./spec/rails_helper.rb:42:in `block (3 levels) in <top (required)>'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/generic/base.rb:15:in `cleaning'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/base.rb:92:in `cleaning'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `call'
          # /Users/justin/.rvm/gems/ruby-2.2.2@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `cleaning'
          # ./spec/rails_helper.rb:41:in `block (2 levels) in <top (required)>'

Finished in 2.49 seconds (files took 2.37 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/features/comments_spec.rb:4 # Add new comment  add post via horizontal, stacked, or inline form

Test out proxying to main rails server from hot module reload (webpack-dev server)

I think we could start the hot reload server with an env var (or even start on different ports in the proc file!) and show this off.

  • Port 3000 for Rails
  • Port 4000 for Webpack Dev Server, proxy last
  • Port 5000 for Webpack Dev Server, using proxy first

By Proxy first or last, that will determine if the callbacks in server.js or the rails server handle the API calls.

Tests are insufficient for JS code

See below image.

If you make an intentional typo, I'd like to see some JS tests pass.

Incidentally, this is caught nicely by the rspec tests.

hello_react

3__default__justin_justinmbp-2___rvm_project_path__zsh_

rendering error

I get lastest version of repo compile all run on my pc and when i try to get main page
Exception in rendering!

Message: Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.

Error: Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.
at invariant (:27969:16)
at traverseAllChildrenImpl (:40373:230)
at traverseAllChildrenImpl (:40329:24)
at traverseAllChildren (:40401:11)
at mapIntoWithKeyPrefixInternal (:40153:4)
at Object.mapChildren as map
at Object.mapValidComponents as map
at renderUl (:47627:49)
at render (:47605:15)
at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (:11703:35)

Document that non-production builds will create large bundle files

Maybe because I'm just familiarizing myself with webpack, but I had to dig around for a while wondering why a very minimal project was generating a 4.5MB bundle.js and noticed that it was due to webpack.rails.config.js setting devtools to "eval-source-map" (which brought that down to 500kb).

Can't run feature tests -- problem and answer

If you get the message below when running rspec, then you'll want to check if you have qt-4.x installed. You need at least qt-5 installed.

brew info qt

Check the output.

Install qt5

brew install qt5

Then you need to

gem uninstall capybara-webkit
QMAKE=/usr/local/Cellar/qt5/5.4.0/bin/qmake bundle install

IMPORTANT Be sure that the path indicated for the QMAKE corresponds to a correct path.

Then run

rspec

and you should see the tests have passed.

Here's the full error:

  add post via horizontal, stacked, or inline form (FAILED - 1)
  HTML screenshot: /Users/justin/j/react/react-webpack-rails-tutorial/tmp/capybara/screenshot_2015-03-26-18-13-04.931.html
  Image screenshot: /Users/justin/j/react/react-webpack-rails-tutorial/tmp/capybara/screenshot_2015-03-26-18-13-04.931.png

Failures:

  1) Add new comment  add post via horizontal, stacked, or inline form
     Failure/Error: click_link 'Horizontal Form'
     Capybara::ElementNotFound:
       Unable to find link "Horizontal Form"
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/capybara-2.4.4/lib/capybara/node/finders.rb:41:in `block in find'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/capybara-2.4.4/lib/capybara/node/base.rb:84:in `synchronize'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/capybara-2.4.4/lib/capybara/node/finders.rb:30:in `find'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/capybara-2.4.4/lib/capybara/node/actions.rb:27:in `click_link'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/capybara-2.4.4/lib/capybara/session.rb:676:in `block (2 levels) in <class:Session>'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/capybara-2.4.4/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
     # ./spec/features/comments_spec.rb:8:in `block (2 levels) in <top (required)>'
     # ./spec/rails_helper.rb:43:in `block (3 levels) in <top (required)>'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/generic/base.rb:15:in `cleaning'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/base.rb:92:in `cleaning'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `call'
     # /Users/justin/.rvm/gems/ruby-2.1.5@rails42/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `cleaning'
     # ./spec/rails_helper.rb:42:in `block (2 levels) in <top (required)>'

Finished in 4.29 seconds (files took 2.4 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/features/comments_spec.rb:5 # Add new comment  add post via horizontal, stacked, or inline form

Small UI enhancements

Live deployment is at http://www.reactrails.com/

  1. Rake task to delete all comments older than one day (couple different options, such as scheduled running of rake task). Provide instructions on how to setup in Heroku Scheduler.
  2. Note that comments older than 24 hours deleted.

@Johnnycus will work on this.

Consider including Lodash in the project

Take a look at this:
https://github.com/shakacode/react-webpack-rails-tutorial/pull/123/files#r42269891

The take away is this:

Array.from(document.getElementsByTagName('meta')).find(tag => tag.name === 'csrf-token')

vs with Lodash:

_.find(document.querySelectorAll('meta'), 'name', 'csrf-token')

I find lodash to be my swiss army knife when coding JS, and it fits in well with React.

In fact, Lodash is already an implicit dependency.

https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/npm-shrinkwrap.json#L2669

Anybody second me?

@alexfedoseev @samnang @josiasds @mapreal19 @dylangrafmyre @rstudner?

nvm 0.12.7 and 0.12.6 have sass issues

libsass has an issue. Maybe there's an update?

08:57:58 hot.1    | Error: `libsass` bindings not found in /Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/vendor/darwin-x64-14/binding.node. Try reinstalling `node-sass`?

If anybody has a PR that fixes this issue...

Thanks in advance.

Full message

foreman start -f Procfile.dev                                                                                                                                                                              ✹ [8:57:48]
08:57:56 web.1    | started with pid 46827
08:57:56 client.1 | started with pid 46828
08:57:56 hot.1    | started with pid 46829
08:57:57 client.1 | Webpack dev build for Rails
08:57:57 hot.1    | sleep: using busy loop fallback
08:57:57 hot.1    | Listening at localhost:3000...
08:57:58 hot.1    | Error: `libsass` bindings not found in /Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/vendor/darwin-x64-14/binding.node. Try reinstalling `node-sass`?
08:57:58 hot.1    |     at Object.sass.getBinaryPath (/Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/lib/extensions.js:148:11)
08:57:58 hot.1    |     at Object.<anonymous> (/Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/lib/index.js:16:36)
08:57:58 hot.1    |     at Module._compile (module.js:460:26)
08:57:58 hot.1    |     at Object.Module._extensions..js (module.js:478:10)
08:57:58 hot.1    |     at Module.load (module.js:355:32)
08:57:58 hot.1    |     at Function.Module._load (module.js:310:12)
08:57:58 hot.1    |     at Module.require (module.js:365:17)
08:57:58 hot.1    |     at require (module.js:384:17)
08:57:58 hot.1    |     at Object.<anonymous> (/Users/justin/a/react-webpack-rails-tutorial/client/node_modules/sass-loader/index.js:4:12)
08:57:58 hot.1    |     at Module._compile (module.js:460:26)
08:57:58 hot.1    | Error: `libsass` bindings not found in /Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/vendor/darwin-x64-14/binding.node. Try reinstalling `node-sass`?
08:57:58 hot.1    |     at Object.sass.getBinaryPath (/Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/lib/extensions.js:148:11)
08:57:58 hot.1    |     at Object.<anonymous> (/Users/justin/a/react-webpack-rails-tutorial/client/node_modules/node-sass/lib/index.js:16:36)
08:57:58 hot.1    |     at Module._compile (module.js:460:26)
08:57:58 hot.1    |     at Object.Module._extensions..js (module.js:478:10)
08:57:58 hot.1    |     at Module.load (module.js:355:32)
08:57:58 hot.1    |     at Function.Module._load (module.js:310:12)
08:57:58 hot.1    |     at Module.require (module.js:365:17)
08:57:58 hot.1    |     at require (module.js:384:17)
08:57:58 hot.1    |     at Object.<anonymous> (/Users/justin/a/react-webpack-rails-tutorial/client/node_modules/sass-loader/index.js:4:12)
08:57:58 hot.1    |     at Module._compile (module.js:460:26)
08:57:58 web.1    | => Booting WEBrick
08:57:58 web.1    | => Rails 4.2.1 application starting in development on http://localhost:4000
08:57:58 web.1    | => Run `rails server -h` for more startup options
08:57:58 web.1    | => Ctrl-C to shutdown server
08:57:59 web.1    | [2015-07-24 08:57:59] INFO  WEBrick 1.3.1
08:57:59 web.1    | [2015-07-24 08:57:59] INFO  ruby 2.2.1 (2015-02-26) [x86_64-darwin14]
08:57:59 web.1    | [2015-07-24 08:57:59] INFO  WEBrick::HTTPServer#start: pid=46827 port=4000
08:57:59 hot.1    | webpack: wait until bundle finished: /comments.json

How to get Rails backend data ? like CSRF token or form URL etc ...

If we don't have view help like react-rails gem, how to get backend data ? pass a window.xxx global javascript variable ? or send a Ajax to backend ? or just write into static jsx file ?

And another question, the page A need Login.jsx component , another page B need Admin.jsx, if all client code has been bundle into one file, how to identify different component on different pages ? or one pages component bundle into one file, include them in rails view like this

dev mode

<script src="http://localhost:8080/assets/<%= controller_name + '_' + action_name%>-bundle.self.js"></script>

What is the best practice, please give your opinions, Thank you all !

Move to node 4.0.0

https://nodejs.org/en/blog/release/v4.0.0/

Node.js v4.0.0 contains V8 v4.5, the same version of V8 shipping with the Chrome web browser today. This brings with it many bonuses for Node.js users, most notably a raft of new ES6 features that are enabled by default including block scoping, classes, typed arrays (Node's Buffer is now backed by Uint8Array), generators, Promises, Symbols, template strings, collections (Map, Set, etc.) and, new to V8 v4.5, arrow functions.

Finally! We can fix server.js to be ES6.

Create a simple example of a React component with remote record to edit

@geoffevason showed me an example of using the no-flux for the simple case of editing a single object with remote call. I think this is a good example, and worth showing.

So long as the following conditions are met, it's OK to have the ajax call to save be at the top level of the component. The simple example is shown here, by the official react docs.

So I'd like to add a 3rd tab in the app showing "simple react".

This will be a nice example to show off the react_on_rails gem

The special conditions for "no redux/flux required" would be:

  1. The only input to the UI is user input or the return of the ajax call with validation messages or status.
  2. We LOCK the UI while the AJAX flight is being sent.
  3. We turn off async comment updates.

This is super simple if we're not displaying the comments list below. However, we can still do this with plain React so long as we disable proactive background fetching of the comments list. Thus, the comments list can be under the top level component, and it's ONLY updated a saved comment is confirmed to be saved at the server. When we get the confirmation, we insert the new comment to the top of the list.

Note, it's the aspect of having async, background comment refreshes that really justifies the use of a flux-type architecture to handle to ensure one way flow of the data.

Any volunteers to help with this? This would be a great learning exercise for React.

cursor_and_railsreacttutorial

var Comment = React.createClass({
  render: function() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
      </div>
    );
  }
});

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
      </div>
    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment, index) {
      return (
        // `key` is a React-specific concept and is not mandatory for the
        // purpose of this tutorial. if you're curious, see more here:
        // http://facebook.github.io/react/docs/multiple-components.html#dynamic-children
        <Comment author={comment.author} key={index}>
          {comment.text}
        </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

React.render(
  <CommentBox url="comments.json" pollInterval={2000} />,
  document.getElementById('content')
);

Custom Fonts Need Example

When using custom fonts, there's an issue in that the sass helper font-url does not work with lib-sass.

The only way I've found around this is to have different files loaded for the boostrap-customization for each of the Rails and Webpack parts, and have these call bootstrap-customization-common.scss

Change Webpack File

This file needs to refer to a file that is webpack specific, like "boostrap-variables-customization-webpack"
and have that file @import "bootstrap-variables-customization";

https://github.com/justin808/react-webpack-rails-tutorial/blob/master/webpack/bootstrap-sass.config.js

module.exports = {
  bootstrapCustomizations: "./assets/stylesheets/_bootstrap-variables-customization.scss",

Change Rails File

This line should refer to something like "boostrap-variables-customization-rails" and have that file @import "bootstrap-variables-customization";

https://github.com/justin808/react-webpack-rails-tutorial/blob/master/app/assets/stylesheets/_bootstrap-custom.scss#L2

@import "bootstrap-variables-customization";

Fix up some imports from the Rails side

These lines should get referenced by
https://github.com/justin808/react-webpack-rails-tutorial/blob/master/app/assets/stylesheets/application.css.scss#L1

By a line at the end of
https://github.com/justin808/react-webpack-rails-tutorial/blob/master/app/assets/stylesheets/_bootstrap-custom.scss#L53

And this file needs to exist, that's referred to in the https://github.com/justin808/react-webpack-rails-tutorial/blob/master/webpack/bootstrap-sass.config.js#L6:

 mainSass: "./_main.scss",

Basically, that file, _main.scss will have access to override any bootstrap styles and will be able to use any bootstrap variables.

The key thing to keep in mind is that the custom variables must be declared right after the bootstrap default variables are loaded and before the bootstrap styles are loaded, and then the app specific custom CSS should run.

I'm also guessing that custom font declarations should go in the place that the custom variables are defined, as the custom variables could indicate fonts that are custom.

Simple, non-redux example improvements

  1. This should take props so as not to depend on the first ajax request: https://github.com/shakacode/react_on_rails/blob/master/app/assets/javascripts/react_on_rails.js#L159
  2. We should not be passing empty props here:
    <%= react_component('SimpleCommentScreen', {}, generator_function: false, prerender: false) %>
  3. We need to break this up into a container component that does the Ajax call and a view component.
    See article on Container Components. This is the file to break up: https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/components/SimpleCommentScreen.jsx
  4. Change /app/assets/javascripts/application.js to not have rails specific startup code. See comment here

@robwise We'll need to incorporate this into the generator.

@josiasds Would you like to take this one on?

cd in procfile not working for me

When trying to run the Procfile.dev it couldn't complain

Error: Cannot find module '/Users/henk/projects/react-webpack-rails-tutorial/server.js'

Looks like foreman 0.78.0 doesn't handle cd's, no idea why.
I got it working by changing the Procfile to this:

web: rails s -p 4000
client: sh -c 'cd client && $(npm bin)/webpack -w --config webpack.rails.config.js'
hot: sh -c 'cd client && node server.js'

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.