shakacode / react_on_rails

Integration of React + Webpack + Rails + rails/webpacker including server-side rendering of React, enabling a better developer experience and faster client performance.

Home Page:https://www.shakacode.com/react-on-rails/docs/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tutorial Generating Correct Project Structure?

seanpaulkelley opened this issue · comments

I followed tutorial:
https://github.com/shakacode/react_on_rails/blob/master/docs/tutorial.md

The app seems to run fine with regard to basic use if input. However I have questions regarding if everything is really setup correctly.

There is no client directory at project root. Some tutorials and docs have it. I am not sure if this is clue something is not setup correctly. I did a new install of rails.

As I understand it, I can put css in rails assets (app/assets/stylesheets) and have them work in react component but on root route I have a css file loading in source and on hello_world there is no css file loading at all.

Incidentally, I tried importing a simple css file in react component but nothing gets styled.

Also, when I make a change to a component's render text and save, there is no live reload happening if running server with
foreman start -f Procfile.dev
I have to refresh page manually.

screenshot from 2017-11-18 09-32-48

Hi @seanpaulkelley, you have 2 main options when setting up React on Rails. You can either

  1. Keep your client-side app completely within the /client directory, as shown in the react-webpack-rails-tutorial. The ShakaCode Team recommends this approach for most projects as it provides the greatest transparency in your webpack and overall client-side setup. The big advantage to this is that almost everything within the /client directory app will apply if you wish to convert your client-side code to pure Single Page Application that runs without Rails.
  2. Use the rails/webpacker Webpack configuration mechanism. The advantage of this is that there is very little code needed to get started. The big disadvantage to this is that you will need to learn the ins and outs of rails/webpacker if you wish to beyond the basic setup, and this sort of knowledge is not going to be particularly applicable if you eventually want to convert your client-side app to a pure Single Page Application that runs without rails.

The basic tutorial and generator use the Webpacker Webpack configuration for 2 reasons:

  1. It's less code to generate and thus less to explain.
  2. rails/webpacker can be viewed as a convention in the Rails community.

My answer in the PR, so far. Comments?

Webpack Configuration: custom setup for Webpack or rails/webpacker?

Version 9 of React on Rails added support for the rails/webpacker view helpers so that Webpack produced assets would no longer pass through the Rails asset pipeline. As part of this change, React on Rails added a configuration option to support customization of the node_modules directory. This allowed React on Rails to support the rails/webpacker configuration of the Webpack configuration.

A key decision in your use React on Rails is whether you go with the rails/webpacker default setup or the traditional React on Rails setup of putting all your client side files under the /client directory. While there are technically 2 independent choices involved, the directory structure and the mechanism of Webpack configuration, for simplicity sake we'll assume that these choices go together.

Traditional React on Rails using the /client directory

Until version 9, all React on Rails apps used the /client directory for configuring React on Rails in terms of the configuration of Webpack and location of your JavaScript and Webpack files, including the node_modules directory. Version 9 changed the default to / for the node_modules location using this value in config/initializers/react_on_rails.rb: config.node_modules_location.

The ShakaCode Team recommends this approach projects beyond the simplest cases as it provides the greatest transparency in your webpack and overall client-side setup. The big advantage to this is that almost everything within the /client directory will apply if you wish to convert your client-side code to a pure Single Page Application that runs without Rails. This allows you to google for how to do something with Webpack configuration and what applies to a non-Rails app will apply just as well to a React on Rails app.

The two best examples of this patten are the react-webpack-rails-tutorial and the integration test example in spec/dummy.

In this case, you don't need to understand the nuances of customization of your Wepback config via the Webpacker mechanism.

rails/webpacker Setup

Typical rails/webpacker apps have a standard directory structure as documented here. If you follow the steps in the the basic tutorial, you will see this pattern in action. In order to customize the Webpack configuration, you need to consult with the rails/webpacker Webpack configuration.

Version 9 made this the default for generated apps for 2 reasons:

  1. It's less code to generate and thus less to explain.
  2. rails/webpacker might be viewed as a convention in the Rails community.

The advantage of this is that there is very little code needed to get started and you don't need to understand really anything about Webpack customization. The big disadvantage to this is that you will need to learn the ins and outs of the [rails/webpacker way to customize Webpack](Webpacker mechanism) (not the plain Webpack way) if you wish to beyond the basic setup, and this sort of knowledge is not going to be particularly applicable if you eventually want to convert your client-side app to a pure Single Page Application that runs without rails.

Overall, consider carefully if you prefer the rails/webpacker directory structure and Webpack configuration, over the placement of all client side files within the /client directory along with conventional Webpack configuration.

See Issue 982: Tutorial Generating Correct Project Structure? to discuss this issue.

This all makes sense. css works fine for me using tutorial respository.

foreman start -f Procfile.hot
Edited component does not auto reload browser on code change. Rails console shows:
[HPM] Error occurred while trying to proxy request /webpack/info?t=1511191882817 from localhost:3035 to http://localhost:3035 (EADDRNOTAVAIL) (https://nodejs.org/api/errors.html#errors_common_system_errors)

Incidentally, the tutorial ( https://github.com/shakacode/react-webpack-rails-tutorial#basic-demo-setup ) line 14 should say port 5000 I think

Generally, what is the best way to start a new project so that I have the recommended structure (/client) but without all the demo stuff in tutorial? Do I just need to start with tutorial repository and remove comments bundle directory (/client/app/bundles/comments) and replace with my own?

@seanpaulkelley Regarding the tutorial and the port, the foreman command generated should change the port to 3000, and an env value of PORT will also set that, maybe to 3000. If not, then this is a bug. Please submit a PR.

In terms of your next question, yes, you can use the setup from the https://github.com/shakacode/react-webpack-rails-tutorial.

Prior versions of the project generator generated a simplified webpack config...Possibly that should be revived at some point? Or maybe just good examples is the best solution?

I think having a simple generator that creates recommended /client structure where I can easily specify a redux option and just start using it would be very helpful.

I am new to React and I just want to know how I can generate a basic setup to try it out with Rails. I also want to be able to include it into existing projects to gradually develop react views to replace rails views in a simple way.

While comprehensive, the tutorial repo is hard for me to get me head around to start.

Hi @justin808 thank you for your great OSS.
I wrote the article regarding this issue
Set up react_on_rails with client folder manually.

Hi @justin808
Can I ask another question about recommended-project-structure?

Which is recommended or is it up to the user situation?

  1. Each domains with startup folder

each-domain-with-startup

example repository
https://github.com/empirical-org/Empirical-Core/tree/develop/client/app/bundles

  1. One startup folder

one-startup-folder

example repository
https://github.com/gauravtiwari/relay-rails-blog/tree/master/client/app/bundles

I'd probably the startup folder in each bundle. #2 doesn't make sense to me.

Hi @justin808, Sorry for bothering you again and again, and really thank you for reply.

Okay, startup folder in each bundle.

Then,

  1. register each startup/registration.js file in webpack entry file ?

=> to make "one big js bundle file" for Turbolinks ?

shakacode-question
https://forum.shakacode.com/t/best-practice-for-multiple-entries-registrations-components-in-webpack-config/993

Or

  1. Separate each startup clientRegistration in webpack entry?
    => Is this good for Turbolinks??
...
module.exports = {
...
  entry: {
...
    app: [
      './app/bundles/HelloWorld/startup/clientRegistration'
    ],
    home: [
      './app/bundles/Home/home'
    ],
    student: [
      './app/bundles/Student/startup/clientRegistration'
    ],
    session: [
      './app/bundles/Session/startup/clientRegistration'
    ],
    // add a new login in bundle here
    login: [
      './app/bundles/Login/startup/clientRegistration'
    ],
    firewall_test: [
      './app/bundles/Firewall_test/firewall_test.js'
    ],
    public: [
      './app/bundles/Public/public.js'
    ],
    tools: [
      './app/bundles/Tools/tools.js'
    ],
  },
...

https://github.com/empirical-org/Empirical-Core/blob/51c3bd061b11107aa438fe350f958d28ceb87042/client/webpack.client.base.config.js#L33-L57

@kohheepeace did you take down your article outlining how to set things up manually?

@jasonblalock Did you find another article for manually setting up the client directory?

@nitincz Unfortunately, I did not

@jasonblalock Here are couple of relevant links to migrate to the recommended directory structure
https://github.com/shakacode/react_on_rails/blob/master/docs/basics/recommended-project-structure.md

rails/webpacker#130

However, after doing these changes, foreman is not able to start as webpacker is not finding the config files (webpacker is still running from bin directory of rails app)