react_on_rails 5.2.0 → 6.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +31 -0
  5. data/PROJECTS.md +11 -2
  6. data/README.md +33 -203
  7. data/app/helpers/react_on_rails_helper.rb +32 -49
  8. data/docs/additional-reading/heroku-deployment.md +2 -35
  9. data/docs/additional-reading/node-server-rendering.md +30 -0
  10. data/docs/additional-reading/rails-assets.md +19 -0
  11. data/docs/additional-reading/rspec-configuration.md +38 -4
  12. data/docs/additional-reading/webpack-dev-server.md +16 -0
  13. data/docs/additional-reading/webpack.md +0 -10
  14. data/docs/api/javascript-api.md +37 -0
  15. data/docs/api/ruby-api-hot-reload-view-helpers.md +42 -0
  16. data/docs/api/ruby-api.md +3 -0
  17. data/docs/basics/generator.md +49 -0
  18. data/docs/{additional-reading → basics}/installation-overview.md +0 -0
  19. data/docs/basics/migrating-from-react-rails.md +17 -0
  20. data/docs/contributor-info/contributing.md +11 -0
  21. data/docs/{coding-style → contributor-info}/linters.md +0 -0
  22. data/lib/generators/USAGE +3 -95
  23. data/lib/generators/react_on_rails/base_generator.rb +10 -43
  24. data/lib/generators/react_on_rails/dev_tests_generator.rb +17 -1
  25. data/lib/generators/react_on_rails/install_generator.rb +0 -6
  26. data/lib/generators/react_on_rails/react_no_redux_generator.rb +3 -17
  27. data/lib/generators/react_on_rails/react_with_redux_generator.rb +4 -21
  28. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev.tt +2 -2
  29. data/lib/generators/react_on_rails/templates/base/base/app/views/hello_world/index.html.erb.tt +3 -4
  30. data/lib/generators/react_on_rails/templates/base/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx.tt +1 -11
  31. data/lib/generators/react_on_rails/templates/base/base/client/node/package.json +10 -0
  32. data/lib/generators/react_on_rails/templates/base/base/client/node/server.js +82 -0
  33. data/lib/generators/react_on_rails/templates/base/base/client/package.json.tt +3 -20
  34. data/lib/generators/react_on_rails/templates/base/base/client/webpack.config.js +58 -0
  35. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt +60 -26
  36. data/lib/generators/react_on_rails/templates/base/base/lib/tasks/assets.rake.tt +1 -4
  37. data/lib/generators/react_on_rails/templates/base/base/lib/tasks/load_test.rake +8 -0
  38. data/lib/generators/react_on_rails/templates/base/base/package.json.tt +0 -12
  39. data/lib/generators/react_on_rails/templates/dev_tests/spec/features/hello_world_spec.rb +1 -1
  40. data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +1 -0
  41. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +1 -7
  42. data/lib/generators/react_on_rails/templates/{base/base/client/app/bundles/HelloWorld/startup/clientRegistration.jsx.tt → no_redux/base/client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx.tt} +7 -1
  43. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/{HelloWorldAppClient.jsx.tt → HelloWorldApp.jsx.tt} +5 -1
  44. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/store/helloWorldStore.jsx +1 -5
  45. data/lib/react_on_rails.rb +2 -1
  46. data/lib/react_on_rails/configuration.rb +17 -5
  47. data/lib/react_on_rails/react_component/options.rb +76 -0
  48. data/lib/react_on_rails/server_rendering_pool.rb +9 -151
  49. data/lib/react_on_rails/server_rendering_pool/exec.rb +166 -0
  50. data/lib/react_on_rails/server_rendering_pool/node.rb +77 -0
  51. data/lib/react_on_rails/test_helper.rb +1 -6
  52. data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +4 -77
  53. data/lib/react_on_rails/test_helper/node_process_launcher.rb +12 -0
  54. data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +4 -28
  55. data/lib/react_on_rails/version.rb +1 -1
  56. data/lib/tasks/assets.rake +115 -0
  57. data/package.json +2 -1
  58. data/rakelib/example_type.rb +3 -10
  59. data/rakelib/examples_config.yml +2 -2
  60. data/react_on_rails.gemspec +1 -0
  61. metadata +41 -20
  62. data/lib/generators/react_on_rails/templates/base/base/REACT_ON_RAILS.md +0 -16
  63. data/lib/generators/react_on_rails/templates/base/base/client/REACT_ON_RAILS_CLIENT_README.md +0 -3
  64. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.base.config.js +0 -65
  65. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.rails.config.js +0 -53
  66. data/lib/generators/react_on_rails/templates/base/server_rendering/client/app/bundles/HelloWorld/startup/serverRegistration.jsx +0 -4
  67. data/lib/generators/react_on_rails/templates/base/server_rendering/client/webpack.server.rails.config.js +0 -39
  68. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx.tt +0 -6
  69. data/lib/generators/react_on_rails/templates/no_redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +0 -6
  70. data/lib/generators/react_on_rails/templates/redux/base/client/app/lib/middlewares/loggerMiddleware.js +0 -21
  71. data/lib/generators/react_on_rails/templates/redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +0 -19
  72. data/lib/react_on_rails/test_helper/webpack_process_checker.rb +0 -54
@@ -87,14 +87,7 @@ module ReactOnRailsHelper
87
87
  # raise_on_prerender_error: <true/false> Default to false. True will raise exception on server
88
88
  # if the JS code throws
89
89
  # Any other options are passed to the content tag, including the id.
90
- def react_component(component_name,
91
- props: {},
92
- prerender: nil,
93
- trace: nil,
94
- replay_console: nil,
95
- raise_on_prerender_error: nil,
96
- id: nil,
97
- html_options: {})
90
+ def react_component(component_name, raw_options = {})
98
91
  # Create the JavaScript and HTML to allow either client or server rendering of the
99
92
  # react_component.
100
93
  #
@@ -104,44 +97,31 @@ module ReactOnRailsHelper
104
97
  # We use this react_component_index in case we have the same component multiple times on the page.
105
98
 
106
99
  react_component_index = next_react_component_index
107
- react_component_name = component_name.camelize # Not sure if we should be doing this (JG)
108
- dom_id = id.presence || "#{component_name}-react-component-#{react_component_index}"
100
+ options = ReactOnRails::ReactComponent::Options.new(name: component_name,
101
+ index: react_component_index,
102
+ options: raw_options)
109
103
 
110
104
  # Setup the page_loaded_js, which is the same regardless of prerendering or not!
111
105
  # The reason is that React is smart about not doing extra work if the server rendering did its job.
112
106
 
113
- props = {} if props.nil?
114
-
115
- prerender = prerender_option(prerender)
116
- trace = trace_option(trace)
117
- replay_console = replay_console_option(replay_console)
118
- raise_on_prerender_error = raise_on_prerender_error_option(raise_on_prerender_error)
119
-
120
- data = {
121
- component_name: react_component_name,
122
- props: props,
123
- trace: trace,
124
- dom_id: dom_id
125
- }
126
-
127
107
  component_specification_tag =
128
108
  content_tag(:div,
129
109
  "",
130
110
  class: "js-react-on-rails-component",
131
- style: ReactOnRails.configuration.skip_display_none ? nil : "display:none",
132
- data: data)
111
+ style: options.style,
112
+ data: options.data)
133
113
 
134
114
  # Create the HTML rendering part
135
- result = server_rendered_react_component_html(props, react_component_name, dom_id,
136
- prerender: prerender,
137
- trace: trace,
138
- raise_on_prerender_error: raise_on_prerender_error)
115
+ result = server_rendered_react_component_html(options.props, options.name, options.dom_id,
116
+ prerender: options.prerender,
117
+ trace: options.trace,
118
+ raise_on_prerender_error: options.raise_on_prerender_error)
139
119
 
140
120
  server_rendered_html = result["html"]
141
121
  console_script = result["consoleReplayScript"]
142
122
 
143
- content_tag_options = html_options
144
- content_tag_options[:id] = dom_id
123
+ content_tag_options = options.html_options
124
+ content_tag_options[:id] = options.dom_id
145
125
 
146
126
  rendered_output = content_tag(:div,
147
127
  server_rendered_html.html_safe,
@@ -151,7 +131,7 @@ module ReactOnRailsHelper
151
131
  result = <<-HTML.html_safe
152
132
  #{component_specification_tag}
153
133
  #{rendered_output}
154
- #{replay_console ? console_script : ''}
134
+ #{options.replay_console ? console_script : ''}
155
135
  HTML
156
136
 
157
137
  prepend_render_rails_context(result)
@@ -290,16 +270,29 @@ module ReactOnRailsHelper
290
270
  # On server `location` option is added (`location = request.fullpath`)
291
271
  # React Router needs this to match the current route
292
272
 
293
- # Make sure that we use up-to-date server-bundle
273
+ # Make sure that we use up-to-date bundle file used for server rendering, which is defined
274
+ # by config file value for config.server_bundle_js_file
294
275
  ReactOnRails::ServerRenderingPool.reset_pool_if_server_bundle_was_modified
295
276
 
296
277
  # Since this code is not inserted on a web page, we don't need to escape props
278
+ #
279
+ # However, as JSON (returned from `props_string(props)`) isn't JavaScript,
280
+ # but we want treat it as such, we need to compensate for the difference.
281
+ #
282
+ # \u2028 and \u2029 are valid characters in strings in JSON, but are treated
283
+ # as newline separators in JavaScript. As no newlines are allowed in
284
+ # strings in JavaScript, this causes an exception.
285
+ #
286
+ # We fix this by replacing these unicode characters with their escaped versions.
287
+ # This should be safe, as the only place they can appear is in strings anyway.
288
+ #
289
+ # Read more here: http://timelessrepo.com/json-isnt-a-javascript-subset
297
290
 
298
291
  wrapper_js = <<-JS
299
292
  (function() {
300
293
  var railsContext = #{rails_context(server_side: true).to_json};
301
294
  #{initialize_redux_stores}
302
- var props = #{props_string(props)};
295
+ var props = #{props_string(props).gsub("\u2028", '\u2028').gsub("\u2029", '\u2029')};
303
296
  return ReactOnRails.serverRenderReactComponent({
304
297
  name: '#{react_component_name}',
305
298
  domNodeId: '#{dom_id}',
@@ -358,8 +351,10 @@ ReactOnRails.setStore('#{store_name}', store);
358
351
  # second parameter passed to both component and store generator functions.
359
352
  def rails_context(server_side:)
360
353
  @rails_context ||= begin
361
- uri = URI.parse(request.original_url)
362
- # uri = URI("http://foo.com:3000/posts?id=30&limit=5#time=1305298413")
354
+ # Using Addressable instead of standard URI to better deal with
355
+ # non-ASCII characters (see https://github.com/shakacode/react_on_rails/pull/405)
356
+ uri = Addressable::URI.parse(request.original_url)
357
+ # uri = Addressable::URI.parse("http://foo.com:3000/posts?id=30&limit=5#time=1305298413")
363
358
 
364
359
  result = {
365
360
  # URL settings
@@ -387,18 +382,6 @@ ReactOnRails.setStore('#{store_name}', store);
387
382
  @rails_context.merge(serverSide: server_side)
388
383
  end
389
384
 
390
- def raise_on_prerender_error_option(val)
391
- val.nil? ? ReactOnRails.configuration.raise_on_prerender_error : val
392
- end
393
-
394
- def trace_option(val)
395
- val.nil? ? ReactOnRails.configuration.trace : val
396
- end
397
-
398
- def prerender_option(val)
399
- val.nil? ? ReactOnRails.configuration.prerender : val
400
- end
401
-
402
385
  def replay_console_option(val)
403
386
  val.nil? ? ReactOnRails.configuration.replay_console : val
404
387
  end
@@ -26,13 +26,13 @@ If for some reason you need custom buildpacks that are not officially supported
26
26
 
27
27
  ### Swap out sqlite for postgres by doing the following:
28
28
 
29
- 1. Delete the line with `sqlite` and replace it with:
29
+ #### 1. Delete the line with `sqlite` and replace it with:
30
30
 
31
31
  ```ruby
32
32
  gem 'pg'
33
33
  ```
34
34
 
35
- 2. Replace your `database.yml` file with this (assuming your app name is "ror")
35
+ #### 2. Replace your `database.yml` file with this (assuming your app name is "ror")
36
36
 
37
37
  ```yml
38
38
  default: &default
@@ -64,36 +64,3 @@ bundle
64
64
  bin/rake db:migrate
65
65
  bin/rake db:setup
66
66
  ```
67
-
68
- 3. Create a rake file to add webpack compilation to asset precompilation. You may already have this file if you used the React on Rails generator.
69
-
70
- ```ruby
71
- # lib/tasks/assets.rake
72
- # The webpack task must run before assets:environment task.
73
- # Otherwise Sprockets cannot find the files that webpack produces.
74
- # This is the secret sauce for how a Heroku deployment knows to create the webpack generated JavaScript files.
75
- Rake::Task["assets:precompile"]
76
- .clear_prerequisites
77
- .enhance(["assets:compile_environment"])
78
-
79
- namespace :assets do
80
- # In this task, set prerequisites for the assets:precompile task
81
- task compile_environment: :webpack do
82
- Rake::Task["assets:environment"].invoke
83
- end
84
-
85
- desc "Compile assets with webpack"
86
- task :webpack do
87
- sh "cd client && npm run build:client"
88
- # If you are doing server rendering
89
- # sh "cd client && npm run build:server"
90
- end
91
-
92
- task :clobber do
93
- rm_r Dir.glob(Rails.root.join("app/assets/webpack/*"))
94
- end
95
- end
96
- ```
97
-
98
-
99
-
@@ -0,0 +1,30 @@
1
+ ## Node Server Rendering
2
+
3
+ ### Warning: this is an experimental feature
4
+
5
+ The default server rendering exploits ExecJS to render react components.
6
+ Node server rendering allows you to use separate NodeJS process as a renderer. The process loads your configured server_bundle_js file and
7
+ then executes javascript to render the component inside its environment. The communication between rails and node occurs
8
+ via socket (`client/node/node.sock`)
9
+
10
+ ### Getting started
11
+
12
+ To use node process just set `server_render_method = "NodeJS"` in `config/initializers/react_on_rails.rb`. To change back
13
+ to ExecJS set `server_render_method = "ExecJS"`
14
+
15
+ ### Configuration
16
+
17
+ You need to configure the name of the server bundle in two places:
18
+
19
+ 1. JavaScript: Change the name of server bundle adjust npm start script in `client/node/package.json`
20
+ 2. Ruby: The configured server bundle file is defined in `config/react_on_rails.rb`, and you'll have a webpack file that creates this. You maybe using the same file for client rendering.
21
+
22
+ ```ruby
23
+ # This is the file used for server rendering of React when using `(prerender: true)`
24
+ # If you are never using server rendering, you may set this to "".
25
+ # If you are using the same file for client and server rendering, having this set probably does
26
+ # not affect performance.
27
+ config.server_bundle_js_file = "webpack-bundle.js"
28
+ ```
29
+
30
+
@@ -0,0 +1,19 @@
1
+ ## Rails assets
2
+
3
+ ### Problem
4
+ When client js uses images in render methods, e.g. `<img src='...' />` or in css, e.g. `background-image: url(...)`
5
+ these assets fail to load. This happens because rails adds digest hashes to filenames
6
+ when compiling assets, e.g. `img1.jpg` becomes `img1-dbu097452jf2v2.jpg`.
7
+
8
+ When compiling its native css Rails transforms all urls and links to digested
9
+ versions, i.e. `background-image: image-url(img1.jpg)` becomes
10
+ `background-image: url(img1-dbu097452jf2v2.jpg)`. However this doesn't happen for js and
11
+ css files compiled by webpack on the client side, because they don't use
12
+ `image-url` and `asset-url` and therefore assets fail to load.
13
+
14
+ ### Solution
15
+
16
+ Create symlinks of non-digested versions to digested versions when Rails assets compile.
17
+ The solution is implemented using `assets:precompile` after-hook. The assets for symlinking
18
+ are defined by `config.symlink_non_digested_assets_regex` in `config/initializers/react_on_rails.rb`.
19
+ To disable symlinks set this parameter to `nil`.
@@ -9,16 +9,50 @@ RSpec.configure do |config|
9
9
  ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
10
10
  ```
11
11
 
12
- You can pass an RSpec metatag as an optional second parameter to this helper method if you want this helper to run on examples other than where `js: true` (default). The helper will compile webpack files at most once per test run. The helper will not compile the webpack files unless they are out of date (stale).
12
+ You can pass an RSpec metatag as an optional second parameter to this helper method if you want this helper to run on examples other than where `js: true` (default). The helper will compile webpack files at most once per test run. The helper will not compile the webpack files unless they are out of date (stale). The helper is configurable in terms of what command is used to prepare the files.
13
13
 
14
14
  Please take note of the following:
15
- - This utility assumes your build tasks for the static generated files are `npm run build:client` and `npm run build:server` and do not have the `--watch` option enabled.
16
- - By default, the webpack processes look for the `app/assets/webpack` folders. If this folder is missing, is empty, or contains files with `mtime`s older than any of the files in your `client` folder, the helper will recompile your assets. You can override this inside of `config/initializers/react_on_rails.rb` by passing a filepath (relative to the root of the app) to the `generated_assets_dir` configuration option.
15
+ - This utility uses your `npm_build_test_command' to build the static generated files. This command **must** not include the `--watch` option. If you have different server and client bundle files, this command **must** create all the bundles.
16
+ - By default, the webpack processes look for the `app/assets/webpack` folders (configured as setting `webpack_generated_files` in the `config/react_on_rails.rb`. If this folder is missing, is empty, or contains files in the `config.webpack_generated_files` list with `mtime`s older than any of the files in your `client` folder, the helper will recompile your assets. You can override the location of these files inside of `config/initializers/react_on_rails.rb` by passing a filepath (relative to the root of the app) to the `generated_assets_dir` configuration option.
17
17
 
18
- If you want to speed up the re-compiling process, you can call `npm run build:dev:client` (and `npm run build:dev:server` if doing server rendering) to have webpack run in "watch" mode and recompile these files in the background, which will be much faster when making incremental changes than compiling from scratch.
18
+ The following `config/react_on_rails.rb` settings **must** match your setup:
19
+ ```ruby
20
+ # Directory where your generated assets go. All generated assets must go to the same directory.
21
+ # Configure this in your webpack config files. This relative to your Rails root directory.
22
+ config.generated_assets_dir = File.join(%w(app assets webpack))
23
+
24
+ # Define the files we need to check for webpack compilation when running tests.
25
+ config.webpack_generated_files = %w( webpack-bundle.js )
26
+
27
+ # If you are using the ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
28
+ # with rspec then this controls what npm command is run
29
+ # to automatically refresh your webpack assets on every test run.
30
+ config.npm_build_test_command = "npm run build:test"
31
+ ```
32
+
33
+ If you want to speed up the re-compiling process, you can call `npm run build:development` (per below script) to have webpack run in "watch" mode and recompile these files in the background, which will be much faster when making incremental changes than compiling from scratch, assuming you have your setup like this:
34
+
35
+ ```
36
+ "scripts": {
37
+ "build:test": "webpack --config webpack.config.js",
38
+ "build:production": "NODE_ENV=production webpack --config webpack.config.js",
39
+ "build:development": "webpack -w --config webpack.config.js"
40
+ },
41
+ ```
19
42
 
20
43
  [spec/dummy](../../spec/dummy) contains examples of how to set the proc files for this purpose.
21
44
 
45
+ ## Hot Reloading
46
+ If you're using the hot reloading setup, you'll be running a Webpack development server to provide the JavaScript and mabye CSS assets to your Rails app. If you're doing server rendering, you'll also have a webpack watch process to refresh the server rendering file. **If your server and client bundles are different**, and you run specs, the client bundle files will not be created until React on Rails detects it's out of date. Then your script to create all bundle files will redo the server bundle file. There's a few simple remedies for this situation:
47
+
48
+ 1. Switch to using static compilation of the webpack bundle files. This way, you're running a Webpack watch process to generate the same files used for tests as well as developmentment. You should have a separate Procfile for doing development using a "static" setup, rather than a "hot" setup.
49
+ 2. Change your Procfile for starting the hot reloading server to also run a webpack process to automatically rebuild a the client assets while also doing hot reloading for browser testing.
50
+
51
+ Note, none of these issues matter if you're using the same file for both server and client side rendering.
52
+
53
+ ## Using RubyMine and other IDEs that save files right before invoking tests
54
+ We had previously tried to allow using a process check to see if a Webpack watch process would already be automatically compiling the files. However, we removed this as it proved to be fragile with various setups. Thus, you want to hit the save keystroke when you save a JavaScript file, and then run your tests. Yes, you might not do this in time, and the test runner may be building the same files as you Webpack watch processes. This will probably happen infrequently, but if this does become an issue, we can look into bring back this functionality ([#398](https://github.com/shakacode/react_on_rails/pull/398)).
55
+
22
56
  If you want to use a testing framework other than RSpec, please submit let us know on the changes you need to do and we'll update the docs.
23
57
 
24
58
  ![2016-01-27_02-36-43](https://cloud.githubusercontent.com/assets/1118459/12611951/7c56d070-c4a4-11e5-8a80-9615f99960d9.png)
@@ -0,0 +1,16 @@
1
+ ## Developing with the Webpack Dev Server
2
+ One of the benefits of using webpack is access to [webpack's dev server](https://webpack.github.io/docs/webpack-dev-server.html) and its [hot module replacement](https://webpack.github.io/docs/hot-module-replacement-with-webpack.html) functionality.
3
+
4
+ The webpack dev server with HMR will apply changes from the code (or styles!) to the browser as soon as you save whatever file you're working on. You won't need to reload the page, and your data will still be there. Start foreman as normal (it boots up the Rails server *and* the webpack HMR dev server at the same time).
5
+
6
+ ```bash
7
+ foreman start -f Procfile.dev
8
+ ```
9
+
10
+ Open your browser to [localhost:3000](http://localhost:3000). Whenever you make changes to your JavaScript code in the `client` folder, they will automatically show up in the browser. Hot module replacement is already enabled by default.
11
+
12
+ Note that **React-related error messages are possibly more helpful when encountered in the dev server** than the Rails server as they do not include noise added by the React on Rails gem.
13
+
14
+ ### Adding Additional Routes for the Dev Server
15
+ As you add more routes to your front-end application, you will need to make the corresponding API for the dev server in `client/server.js`. See our example `server.js` from our [tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client%2Fserver-express.js).
16
+
@@ -12,8 +12,6 @@ You need both include `react-dom/server` and `react` as values for `entry`, like
12
12
  // See use of 'vendor' in the CommonsChunkPlugin inclusion below.
13
13
  vendor: [
14
14
  'babel-core/polyfill',
15
- 'jquery',
16
- 'jquery-ujs',
17
15
  'react',
18
16
  'react-dom',
19
17
  ],
@@ -25,14 +23,6 @@ and you need to expose them:
25
23
  // React is necessary for the client rendering:
26
24
  {test: require.resolve('react'), loader: 'expose?React'},
27
25
  {test: require.resolve('react-dom'), loader: 'expose?ReactDOM'},
28
- {test: require.resolve('jquery'), loader: 'expose?jQuery'},
29
- {test: require.resolve('jquery'), loader: 'expose?$'},
30
- ```
31
-
32
- `webpack.server.config.js` is similar, but substitute:
33
-
34
- ```
35
- entry: ['./yourCode', 'react-dom/server', 'react'],
36
26
  ```
37
27
 
38
28
  and use this line rather than `{test: require.resolve('react-dom'), loader: 'expose?ReactDOM'},`:
@@ -0,0 +1,37 @@
1
+ # ReactOnRails JavaScript API
2
+ The best source of docs is the main [ReactOnRails.js](node_package/src/ReactOnRails.js) file. Here's a quick summary. No guarantees that this won't be outdated!
3
+
4
+ ```js
5
+ /**
6
+ * Main entry point to using the react-on-rails npm package. This is how Rails will be able to
7
+ * find you components for rendering.
8
+ * @param components (key is component name, value is component)
9
+ */
10
+ register(components)
11
+
12
+ /**
13
+ * Allows registration of store generators to be used by multiple react components on one Rails
14
+ * view. store generators are functions that take one arg, props, and return a store. Note that
15
+ * the setStore API is different in tha it's the actual store hydrated with props.
16
+ * @param stores (key is store name, value is the store generator)
17
+ */
18
+ registerStore(stores)
19
+
20
+ /**
21
+ * Allows retrieval of the store by name. This store will be hydrated by any Rails form props.
22
+ * Pass optional param throwIfMissing = false if you want to use this call to get back null if the
23
+ * store with name is not registered.
24
+ * @param name
25
+ * @param throwIfMissing Defaults to true. Set to false to have this call return undefined if
26
+ * there is no store with the given name.
27
+ * @returns Redux Store, possibly hydrated
28
+ */
29
+ getStore(name, throwIfMissing = true )
30
+
31
+ /**
32
+ * Set options for ReactOnRails, typically before you call ReactOnRails.register
33
+ * Available Options:
34
+ * `traceTurbolinks: true|false Gives you debugging messages on Turbolinks events
35
+ */
36
+ setOptions(options)
37
+ ```
@@ -0,0 +1,42 @@
1
+ ## Hot Reloading View Helpers
2
+ The `env_javascript_include_tag` and `env_stylesheet_link_tag` support the usage of a webpack dev server for providing the JS and CSS assets during development mode. See the [shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/) for a working example.
3
+
4
+ The key options are `static` and `hot` which specify what you want for static vs. hot. Both of these params are optional, and support either a single value, or an array.
5
+
6
+ static vs. hot is picked based on whether `ENV["REACT_ON_RAILS_ENV"] == "HOT"`
7
+
8
+ ```erb
9
+ <%= env_stylesheet_link_tag(static: 'application_static',
10
+ hot: 'application_non_webpack',
11
+ media: 'all',
12
+ 'data-turbolinks-track' => true) %>
13
+
14
+ <!-- These do not use turbolinks, so no data-turbolinks-track -->
15
+ <!-- This is to load the hot assets. -->
16
+
17
+ <!-- Note, you can have multiple files here. It's an array. -->
18
+ <%= env_javascript_include_tag(hot: ['http://localhost:3500/webpack-bundle.js]') %>
19
+
20
+ <!-- These do use turbolinks -->
21
+ <%= env_javascript_include_tag(static: 'application_static',
22
+ hot: 'application_non_webpack',
23
+ 'data-turbolinks-track' => true) %>
24
+ ```
25
+
26
+ See application.html.erb for usage example and [application.html.erb](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/app%2Fviews%2Flayouts%2Fapplication.html.erb)
27
+
28
+ Helper to set CSS and JS assets depending on if we want static or "hot", which means from the Webpack dev server.
29
+
30
+ In this example, `application_non_webpack` is simply a CSS asset pipeline file which includes styles not placed in the webpack build. The same can be said for `application_non_webpack` for JS files. Note, the suffix is not used in the helper calls.
31
+
32
+ We don't need styles from the webpack build, as those will come via the JavaScript include tags.
33
+
34
+ The key options are `static` and `hot` which specify what you want for static vs. hot. Both of
35
+ these params are optional, and support either a single value, or an array.
36
+
37
+ ```erb
38
+ <%= env_stylesheet_link_tag(static: 'application_static',
39
+ hot: 'application_non_webpack',
40
+ media: 'all',
41
+ 'data-turbolinks-track' => true) %>
42
+ ```
@@ -0,0 +1,3 @@
1
+ PENDING:
2
+
3
+ Should we document the view helpers here concisely?
@@ -0,0 +1,49 @@
1
+ - [Generator](#generator)
2
+ - [Understanding the Organization of the Generated Client Code](#understanding-the-organization-of-the-generated-client-code)
3
+ - [Redux](#redux)
4
+ - [Multiple React Components on a Page with One Store](#multiple-react-components-on-a-page-with-one-store)
5
+ - [Using Images and Fonts](#using-images-and-fonts)
6
+
7
+ The `react_on_rails:install` generator combined with the example pull requests of generator runs will get you up and running efficiently. There's a fair bit of setup with integrating Webpack with Rails. Defaults for options are such that the default is for the flag to be off. For example, the default for `-R` is that `redux` is off, and the default of `-b` is that `skip-bootstrap` is off.
8
+
9
+ Run `rails generate react_on_rails:install --help` for descriptions of all available options:
10
+
11
+ ```
12
+ Usage:
13
+ rails generate react_on_rails:install [options]
14
+
15
+ Options:
16
+ -R, [--redux], [--no-redux] # Install Redux gems and Redux version of Hello World Example
17
+
18
+ Runtime options:
19
+ -f, [--force] # Overwrite files that already exist
20
+ -p, [--pretend], [--no-pretend] # Run but do not make any changes
21
+ -q, [--quiet], [--no-quiet] # Suppress status output
22
+ -s, [--skip], [--no-skip] # Skip files that already exist
23
+
24
+ Description:
25
+ Create react on rails files for install generator.
26
+ ```
27
+
28
+ For a clear example of what each generator option will do, see our generator results repo: [Generator Results](https://github.com/shakacode/react_on_rails-generator-results/blob/master/README.md). Each pull request shows a git "diff" that highlights the changes that the generator has made. Another good option is to create a simple test app per the [Tutorial](docs/tutorial.md).
29
+
30
+ ### Understanding the Organization of the Generated Client Code
31
+ The generated client code follows our organization scheme. Each unique set of functionality, is given its own folder inside of `client/app/bundles`. This encourages for modularity of *domains*.
32
+
33
+ Inside of the generated "HelloWorld" domain you will find the following folders:
34
+
35
+ + `startup`: This contains the entry point files for webpack. It defaults to a single file that is used for server and client compilation, but if these need to be different, then you can create two webpack configurations with separate endpoints.
36
+ + `containers`: "smart components" (components that have functionality and logic that is passed to child "dumb components").
37
+ + `components`: includes "dumb components", or components that simply render their properties and call functions given to them as properties by a parent component. Ultimately, at least one of these dumb components will have a parent container component.
38
+
39
+ You may also notice the `app/lib` folder. This is for any code that is common between bundles and therefore needs to be shared (for example, middleware).
40
+
41
+ ### Redux
42
+ If you have used the `--redux` generator option, you will notice the familiar additional redux folders in addition to the aforementioned folders. The Hello World example has also been modified to use Redux.
43
+
44
+ Note the organizational paradigm of "bundles". These are like application domains and are used for grouping your code into webpack bundles, in case you decide to create different bundles for deployment. This is also useful for separating out logical parts of your application. The concept is that each bundle will have it's own Redux store. If you have code that you want to reuse across bundles, including components and reducers, place them under `/client/app/lib`.
45
+
46
+ ### Using Images and Fonts
47
+ The generator has amended the folders created in `client/assets/` to Rails's asset path. We recommend that if you have any existing assets that you want to use with your client code, you should move them to these folders and use webpack as normal. This allows webpack's development server to have access to your assets, as it will not be able to see any assets in the default Rails directories which are above the `/client` directory.
48
+
49
+ Alternatively, if you have many existing assets and don't wish to move them, you could consider creating symlinks from client/assets that point to your Rails assets folders inside of `app/assets/`. The assets there will then be visible to both Rails and webpack.