react_on_rails 11.2.2 → 12.0.0.pre.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +320 -0
- data/.eslintignore +2 -1
- data/.eslintrc +23 -1
- data/.github/FUNDING.yml +1 -0
- data/.gitignore +3 -1
- data/.prettierignore +10 -1
- data/.prettierrc +3 -0
- data/.rubocop.yml +37 -11
- data/.travis.yml +9 -20
- data/CHANGELOG.md +73 -6
- data/CONTRIBUTING.md +60 -71
- data/Gemfile +3 -4
- data/{COMM-LICENSE → REACT-ON-RAILS-PRO-LICENSE} +6 -9
- data/README.md +137 -95
- data/Rakefile +0 -7
- data/SUMMARY.md +9 -12
- data/book.json +5 -5
- data/docs/additional-reading/asset-pipeline.md +8 -16
- data/docs/additional-reading/react-helmet.md +30 -10
- data/docs/additional-reading/react-router.md +52 -75
- data/docs/additional-reading/server-rendering-tips.md +12 -7
- data/docs/api/javascript-api.md +3 -3
- data/docs/api/redux-store-api.md +4 -2
- data/docs/api/view-helpers-api.md +7 -8
- data/docs/basics/configuration.md +83 -69
- data/docs/basics/deployment.md +2 -4
- data/docs/basics/heroku-deployment.md +24 -0
- data/docs/basics/hmr-and-hot-reloading-with-the-webpack-dev-server.md +49 -0
- data/docs/basics/i18n.md +45 -23
- data/docs/basics/installation-into-an-existing-rails-app.md +4 -9
- data/docs/basics/minitest-configuration.md +31 -0
- data/docs/basics/react-server-rendering.md +1 -1
- data/docs/basics/recommended-project-structure.md +5 -22
- data/docs/basics/{generator-functions-and-railscontext.md → render-functions-and-railscontext.md} +59 -21
- data/docs/basics/rspec-configuration.md +29 -18
- data/docs/basics/upgrading-react-on-rails.md +69 -3
- data/docs/basics/webpack-configuration.md +18 -8
- data/docs/contributor-info/errors-with-hooks.md +45 -0
- data/docs/contributor-info/pull-requests.md +44 -0
- data/docs/misc/doctrine.md +1 -1
- data/docs/{misc-pending → outdated}/code-splitting.md +12 -8
- data/docs/{basics → outdated}/how-react-on-rails-works.md +8 -4
- data/docs/{misc-pending → outdated}/manual-installation-overview.md +5 -5
- data/docs/{additional-reading → outdated}/rails-assets-relative-paths.md +3 -3
- data/docs/{misc-pending → outdated}/rails-assets.md +2 -12
- data/docs/{misc → outdated}/rails3.md +0 -0
- data/docs/testimonials/testimonials.md +3 -3
- data/docs/tutorial.md +96 -70
- data/jest.config.js +4 -0
- data/lib/generators/react_on_rails/base_generator.rb +2 -2
- data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
- data/lib/generators/react_on_rails/generator_helper.rb +4 -6
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +3 -1
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hmr +26 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +20 -40
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +4 -1
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +4 -8
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.js +1 -3
- data/lib/react_on_rails.rb +3 -1
- data/lib/react_on_rails/configuration.rb +58 -28
- data/lib/react_on_rails/error.rb +2 -0
- data/lib/react_on_rails/helper.rb +48 -92
- data/lib/react_on_rails/json_parse_error.rb +2 -0
- data/lib/react_on_rails/locales/base.rb +150 -0
- data/lib/react_on_rails/locales/to_js.rb +37 -0
- data/lib/react_on_rails/locales/to_json.rb +27 -0
- data/lib/react_on_rails/prerender_error.rb +11 -15
- data/lib/react_on_rails/react_component/render_options.rb +4 -0
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +41 -46
- data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +7 -8
- data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +17 -0
- data/lib/react_on_rails/utils.rb +14 -19
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +1 -0
- data/lib/react_on_rails/webpacker_utils.rb +19 -2
- data/lib/tasks/assets.rake +29 -47
- data/lib/tasks/locale.rake +4 -2
- data/package-scripts.yml +11 -8
- data/package.json +29 -28
- data/rakelib/dummy_apps.rake +1 -9
- data/rakelib/example_type.rb +3 -1
- data/rakelib/examples.rake +3 -0
- data/rakelib/lint.rake +2 -7
- data/rakelib/node_package.rake +2 -2
- data/rakelib/release.rake +0 -6
- data/rakelib/run_rspec.rake +5 -18
- data/react_on_rails.gemspec +4 -5
- data/tsconfig.json +14 -0
- data/webpackConfigLoader.js +3 -2
- data/yarn.lock +4333 -2209
- metadata +47 -57
- data/Gemfile.rails32 +0 -73
- data/docs/additional-reading/babel.md +0 -5
- data/docs/additional-reading/heroku-deployment.md +0 -92
- data/docs/additional-reading/hot-reloading-rails-development-asset-pipeline.md +0 -47
- data/docs/api/ruby-api-hot-reload-view-helpers.md +0 -44
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-server +0 -12
- data/lib/react_on_rails/assets_precompile.rb +0 -153
- data/lib/react_on_rails/locales_to_js.rb +0 -138
data/book.json
CHANGED
@@ -7,12 +7,12 @@
|
|
7
7
|
"url": "https://github.com/shakacode/react_on_rails/"
|
8
8
|
},
|
9
9
|
"sharing": {
|
10
|
-
"facebook":
|
11
|
-
"twitter":
|
12
|
-
"google":
|
13
|
-
"weibo":
|
10
|
+
"facebook": true,
|
11
|
+
"twitter": true,
|
12
|
+
"google": true,
|
13
|
+
"weibo": true,
|
14
14
|
"instapaper": true,
|
15
|
-
"vk":
|
15
|
+
"vk": true
|
16
16
|
}
|
17
17
|
}
|
18
18
|
}
|
@@ -1,20 +1,12 @@
|
|
1
|
-
# Asset Pipeline
|
1
|
+
# Asset Pipeline with React on Rails
|
2
2
|
|
3
|
-
|
3
|
+
In general, you should not be mixing the asset pipeline with rails/webpacker and React on Rails.
|
4
4
|
|
5
|
-
|
5
|
+
If you're using React, then all of your CSS and images should be under either `/client` or
|
6
|
+
`/app/javascript` or wherever you want your client side application.
|
6
7
|
|
8
|
+
If you are incrementally migrating a large application, your main concern will be how to minimize
|
9
|
+
duplication of styles and images between your old application and the new one.
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
This option still works for your `/config/initializers/react_on_rails.rb` if you are still using the
|
11
|
-
asset pipeline.
|
12
|
-
```
|
13
|
-
################################################################################
|
14
|
-
# MISCELLANEOUS OPTIONS
|
15
|
-
################################################################################
|
16
|
-
# If you want to use webpack for CSS and images, and still use the asset pipeline,
|
17
|
-
# see https://github.com/shakacode/react_on_rails/blob/master/docs/additional-reading/rails-assets.md
|
18
|
-
# And you will use a setting like this.
|
19
|
-
config.symlink_non_digested_assets_regex = /\.(png|jpg|jpeg|gif|tiff|woff|ttf|eot|svg|map)/
|
20
|
-
```
|
11
|
+
Please email [justin@shakacode.com](mailto:justin@shakacode.com) if you would be interested in help
|
12
|
+
to migrate a larger application.
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# Using React Helmet to build `<head>` content
|
2
2
|
|
3
3
|
## Installation and general usage
|
4
|
-
See https://github.com/nfl/react-helmet for details
|
4
|
+
See [nfl/react-helmet](https://github.com/nfl/react-helmet) for details on how to use this package.
|
5
|
+
Run `yarn add react-helmet` to add this package to your application.
|
5
6
|
|
6
7
|
## Example
|
7
8
|
Here is what you need to do in order to configure your Rails application to work with **ReactHelmet**.
|
8
9
|
|
9
|
-
Create
|
10
|
+
Create a render-function for server rendering like this:
|
10
11
|
|
11
12
|
```javascript
|
12
13
|
export default (props, _railsContext) => {
|
@@ -20,17 +21,35 @@ export default (props, _railsContext) => {
|
|
20
21
|
return { renderedHtml };
|
21
22
|
};
|
22
23
|
```
|
23
|
-
You can add more **helmet** properties to result, e.g. **meta**, **base** and so on. See https://github.com/nfl/react-helmet#server-usage.
|
24
|
+
You can add more **helmet** properties to the result, e.g. **meta**, **base** and so on. See https://github.com/nfl/react-helmet#server-usage.
|
24
25
|
|
25
|
-
Use regular component or
|
26
|
+
Use a regular React functional or class component or a render-function for your client-side bundle:
|
26
27
|
|
27
28
|
```javascript
|
28
|
-
|
29
|
+
// React functional component
|
30
|
+
export default (props) => (
|
29
31
|
<App {...props} />
|
30
32
|
);
|
31
33
|
```
|
32
34
|
|
33
|
-
|
35
|
+
Or a render-function. Note you can't return just the JSX (React element), but you need to return
|
36
|
+
either a React functional or class component.
|
37
|
+
```javascript
|
38
|
+
// React functional component
|
39
|
+
export default (props, railsContext) => (
|
40
|
+
() => <App {{railsContext, ...props}} />
|
41
|
+
);
|
42
|
+
```
|
43
|
+
|
44
|
+
Note, this doesn't work, because this function just returns a React element rather than a React component
|
45
|
+
```javascript
|
46
|
+
// React functional component
|
47
|
+
export default (props, railsContext) => (
|
48
|
+
<App {{railsContext, ...props}} />
|
49
|
+
);
|
50
|
+
```
|
51
|
+
|
52
|
+
Put the **ReactHelmet** component somewhere in your `<App>`:
|
34
53
|
```javascript
|
35
54
|
import { Helmet } from 'react-helmet';
|
36
55
|
|
@@ -55,15 +74,18 @@ ReactOnRails.register({
|
|
55
74
|
});
|
56
75
|
```
|
57
76
|
```javascript
|
77
|
+
// Note the import from the server file.
|
58
78
|
import ReactHelmetApp from '../ReactHelmetServerApp';
|
59
79
|
|
60
80
|
ReactOnRails.register({
|
61
81
|
ReactHelmetApp
|
62
82
|
});
|
63
83
|
```
|
64
|
-
Now when the `react_component_hash` helper is called with **"ReactHelmetApp"** as a first argument it
|
84
|
+
Now when the `react_component_hash` helper is called with **"ReactHelmetApp"** as a first argument it
|
85
|
+
will return a hash instead of HTML string. Note, there is no need to specify "prerender" as it would not
|
86
|
+
make sense to use react_component_hash without server rendering:
|
65
87
|
```ruby
|
66
|
-
<% react_helmet_app = react_component_hash("ReactHelmetApp",
|
88
|
+
<% react_helmet_app = react_component_hash("ReactHelmetApp", props: { hello: "world" }, trace: true) %>
|
67
89
|
|
68
90
|
<% content_for :title do %>
|
69
91
|
<%= react_helmet_app['title'] %>
|
@@ -76,5 +98,3 @@ So now we're able to insert received title tag to our application layout:
|
|
76
98
|
```ruby
|
77
99
|
<%= yield(:title) if content_for?(:title) %>
|
78
100
|
```
|
79
|
-
|
80
|
-
Note: Use of `react_component` for this functionality is deprecated. Please use `react_component_hash` instead.
|
@@ -1,39 +1,28 @@
|
|
1
|
+
_This article needs updating for the latest version of React Router_
|
2
|
+
|
1
3
|
# Using React Router
|
2
4
|
|
3
|
-
React on Rails supports the use of React Router. Client-side code doesn't need any special configuration for the React on Rails gem. Implement React Router how you normally would. Note, you might want to avoid using Turbolinks as both Turbolinks and React-Router will be trying to handle the back and forward buttons. If you get this figured out, please do share with the community! Otherwise, you might have to tweak the basic settings for Turbolinks, and this may or may not be worth the effort.
|
4
5
|
|
5
|
-
|
6
|
+
React on Rails supports the use of React Router. Client-side code doesn't need any special configuration for the React on Rails gem. Implement React Router how you normally would. Note, you might want to avoid using Turbolinks as both Turbolinks and React-Router will be trying to handle the back and forward buttons. If you get this figured out, please do share with the community! Otherwise, you might have to tweak the basic settings for Turbolinks, and this may or may not be worth the effort.
|
6
7
|
|
7
8
|
If you are working with the HelloWorldApp created by the react_on_rails generator, then the code below corresponds to the module in `client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx`.
|
8
9
|
|
9
10
|
```js
|
11
|
+
|
12
|
+
import { BrowserRouter, Switch } from 'react-router-dom'
|
13
|
+
import routes from './routes.jsx'
|
14
|
+
|
10
15
|
const RouterApp = (props, railsContext) => {
|
11
|
-
let error;
|
12
|
-
let redirectLocation;
|
13
|
-
let routeProps;
|
14
|
-
const { location } = railsContext;
|
15
|
-
|
16
16
|
// create your hydrated store
|
17
17
|
const store = createStore(props);
|
18
|
-
|
19
|
-
// See https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md
|
20
|
-
match({ routes, location }, (_error, _redirectLocation, _routeProps) => {
|
21
|
-
error = _error;
|
22
|
-
redirectLocation = _redirectLocation;
|
23
|
-
routeProps = _routeProps;
|
24
|
-
});
|
25
|
-
|
26
|
-
// This tell react_on_rails to skip server rendering any HTML. Note, client rendering
|
27
|
-
// will handle the redirect. What's key is that we don't try to render.
|
28
|
-
// Critical to return the Object properties to match this { error, redirectLocation }
|
29
|
-
if (error || redirectLocation) {
|
30
|
-
return { error, redirectLocation };
|
31
|
-
}
|
32
|
-
|
33
|
-
// Important that you don't do this if you are redirecting or have an error.
|
18
|
+
|
34
19
|
return (
|
35
20
|
<Provider store={store}>
|
36
|
-
<
|
21
|
+
<BrowserRouter>
|
22
|
+
<Switch>
|
23
|
+
{routes}
|
24
|
+
</Switch>
|
25
|
+
</BrowserRouter>
|
37
26
|
</Provider>
|
38
27
|
);
|
39
28
|
};
|
@@ -50,64 +39,52 @@ For a fleshed out integration of react_on_rails with react-router, check out [Re
|
|
50
39
|
|
51
40
|
# Server Rendering Using React Router V4
|
52
41
|
|
53
|
-
Your
|
42
|
+
Your render function may not return an object with the property `renderedHtml`. Thus, you call
|
54
43
|
renderToString() and return an object with this property.
|
55
44
|
|
56
45
|
This example **only applies to server rendering** and should be only used in the server side bundle.
|
57
46
|
|
58
|
-
From the [original example in the ReactRouter docs](https://react-router.
|
47
|
+
From the [original example in the ReactRouter docs](https://github.com/ReactTraining/react-router/blob/v4.3.1/packages/react-router-dom/docs/guides/server-rendering.md)
|
59
48
|
|
60
49
|
```javascript
|
61
50
|
import React from 'react'
|
62
51
|
import { renderToString } from 'react-dom/server'
|
63
|
-
import {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
markup = renderToString(
|
102
|
-
<ServerRouter
|
103
|
-
location={location}
|
104
|
-
context={context}
|
105
|
-
>
|
106
|
-
<App/>
|
107
|
-
</ServerRouter>
|
108
|
-
)
|
109
|
-
}
|
110
|
-
return { renderedHtml: markup };
|
111
|
-
}
|
52
|
+
import { StaticRouter } from 'react-router'
|
53
|
+
import { Provider } from 'react-redux'
|
54
|
+
import ReactOnRails from 'react-on-rails'
|
55
|
+
|
56
|
+
// App.jsx from src/client/App.jsx
|
57
|
+
import App from '../App'
|
58
|
+
|
59
|
+
const ReactServerRenderer = (props, railsContext) => {
|
60
|
+
const context = {}
|
61
|
+
|
62
|
+
// commentStore from src/server/store/commentStore
|
63
|
+
const store = ReactOnRails.getStore('../store/commentStore')
|
64
|
+
|
65
|
+
// Route Store generated from react-on-rails
|
66
|
+
|
67
|
+
const { location } = railsContext
|
68
|
+
|
69
|
+
const html = ReactDOMServer.renderToString(
|
70
|
+
<Provider store={store}>
|
71
|
+
<StaticRouter
|
72
|
+
location={location}
|
73
|
+
context={context}
|
74
|
+
props={props}
|
75
|
+
>
|
76
|
+
<App />
|
77
|
+
</StaticRouter>
|
78
|
+
</ Provider>
|
79
|
+
)
|
80
|
+
|
81
|
+
if (context.url) {
|
82
|
+
// Somewhere a `<Redirect>` was rendered
|
83
|
+
redirect(301, context.url)
|
84
|
+
} else {
|
85
|
+
// we're good, send the response
|
86
|
+
return { renderedHtml: html };
|
87
|
+
}
|
88
|
+
}
|
112
89
|
}
|
113
90
|
```
|
@@ -1,14 +1,19 @@
|
|
1
1
|
# Server Rendering Tips
|
2
2
|
|
3
|
-
|
3
|
+
For the best performance with Server Rendering, consider using [React on Rails Pro]
|
4
|
+
|
5
|
+
Be sure to use mini_racer. See [issues/428](https://github.com/shakacode/react_on_rails/issues/428).
|
6
|
+
|
7
|
+
|
4
8
|
|
5
9
|
## General Tips
|
6
|
-
- Your code can't reference `document`. Server side JS execution does not have access to `document`,
|
7
|
-
other libs won't work in this environment. You can debug this by putting in
|
8
|
-
statements in your code.
|
9
|
-
- You can conditionally avoid running code that references document by
|
10
|
-
|
11
|
-
|
10
|
+
- Your code can't reference `document`. Server side JS execution does not have access to `document`,
|
11
|
+
so jQuery and some other libs won't work in this environment. You can debug this by putting in
|
12
|
+
`console.log` statements in your code.
|
13
|
+
- You can conditionally avoid running code that references document by either checking if `window`
|
14
|
+
is defined or using the "railsContext"
|
15
|
+
your top level react component. Since the passed in props Hash from the view helper applies to
|
16
|
+
client and server side code, the best way to do this is to use a render function.
|
12
17
|
- If you're serious about server rendering, it's worth the effort to have different entry points for client and server rendering. It's worth the extra complexity. The point is that you have separate files for top level client or server side, and you pass some extra option indicating that rendering is happening server side.
|
13
18
|
- You can enable Node.js server rendering via [React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki).
|
14
19
|
|
data/docs/api/javascript-api.md
CHANGED
@@ -25,10 +25,10 @@ The best source of docs is the main [ReactOnRails.js](https://github.com/shakaco
|
|
25
25
|
/**
|
26
26
|
* Main entry point to using the react-on-rails npm package. This is how Rails will be able to
|
27
27
|
* find you components for rendering. Components get called with props, or you may use a
|
28
|
-
* "
|
28
|
+
* "render function" to return a React component or an object with the following shape:
|
29
29
|
* { renderedHtml, redirectLocation, error }.
|
30
|
-
* For server rendering, if you wish to return multiple HTML strings from a
|
31
|
-
* you may return an Object from your
|
30
|
+
* For server rendering, if you wish to return multiple HTML strings from a render function,
|
31
|
+
* you may return an Object from your render function with a single top level property of
|
32
32
|
* renderedHtml. Inside this Object, place a key called componentHtml, along with any other
|
33
33
|
* needed keys. This is useful when you using side effects libraries like react helmet.
|
34
34
|
* Your Ruby code with get this Object as a Hash containing keys componentHtml and any other
|
data/docs/api/redux-store-api.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Redux Store
|
2
2
|
|
3
|
-
|
3
|
+
_This redux API is no longer recommended as it prevents dynamic code splitting for performance. Instead, you should use the standard react_component view helper passing in a "render function."_
|
4
4
|
|
5
|
-
|
5
|
+
You don't need to use the `redux_store` api to use redux. This api was setup to support multiple calls to `react_component` on one page that all talk to the same redux store.
|
6
|
+
|
7
|
+
If you are only rendering one react component on a page, as is typical to do a "Single Page App" in React, then you should _probably_ pass the props to your React component in a "render function."
|
6
8
|
|
7
9
|
Consider using the `redux_store` helper for the two following use cases:
|
8
10
|
|
@@ -22,13 +22,13 @@ Uncommonly used options:
|
|
22
22
|
id: nil,
|
23
23
|
```
|
24
24
|
|
25
|
-
- **component_name:** Can be a React component, created using an ES6 class or a
|
25
|
+
- **component_name:** Can be a React component, created using an ES6 class or a render function that returns a React component (or, only on the server side, an object with shape { redirectLocation, error, renderedHtml }), or a "renderer function" that manually renders a React component to the dom (client side only).
|
26
26
|
All options except `props, id, html_options` will inherit from your `react_on_rails.rb` initializer, as described [here](../basics/configuration.md).
|
27
27
|
- **general options:**
|
28
28
|
- **props:** Ruby Hash which contains the properties to pass to the react object, or a JSON string. If you pass a string, we'll escape it for you.
|
29
29
|
- **prerender:** enable server-side rendering of a component. Set to false when debugging!
|
30
30
|
- **id:** Id for the div, will be used to attach the React component. This will get assigned automatically if you do not provide an id. Must be unique.
|
31
|
-
- **html_options:** Any other HTML options get placed on the added div for the component. For example, you can set a class (or inline style) on the outer div so that it behaves like a span, with the styling of `display:inline-block`.
|
31
|
+
- **html_options:** Any other HTML options get placed on the added div for the component. For example, you can set a class (or inline style) on the outer div so that it behaves like a span, with the styling of `display:inline-block`. You may also use an option of `tag: "span"` to replace the use of the default DIV tag to be a SPAN tag.
|
32
32
|
- **trace:** set to true to print additional debugging information in the browser. Defaults to true for development, off otherwise. Only on the **client side** will you will see the `railsContext` and your props.
|
33
33
|
- **random_dom_id:** True to automatically generate random dom ids when using multiple instances of the same React component on one Rails view.
|
34
34
|
- **options if prerender (server rendering) is true:**
|
@@ -45,7 +45,7 @@ adding meta-tags to a page. It is exactly like react_component except for the fo
|
|
45
45
|
|
46
46
|
1. `prerender: true` is automatically added to options, as this method doesn't make sense for
|
47
47
|
client only rendering.
|
48
|
-
2. Your JavaScript
|
48
|
+
2. Your JavaScript render function for server rendering must return an Object rather than a React Component.
|
49
49
|
3. Your view code must expect an object and not a string.
|
50
50
|
|
51
51
|
Here is an example of ERB view code:
|
@@ -73,7 +73,6 @@ export default (props, _railsContext) => {
|
|
73
73
|
};
|
74
74
|
return { renderedHtml };
|
75
75
|
};
|
76
|
-
|
77
76
|
```
|
78
77
|
|
79
78
|
------------
|
@@ -99,11 +98,11 @@ You can call `rails_context` or `rails_context(server_side: true|false)` from yo
|
|
99
98
|
|
100
99
|
### Renderer Functions (function that will call ReactDOM.render or ReactDOM.hydrate)
|
101
100
|
|
102
|
-
A "renderer function" is a
|
101
|
+
A "renderer function" is a render function that accepts three arguments (rather than 2): `(props, railsContext, domNodeId) => { ... }`. Instead of returning a React component, a renderer is responsible for installing a callback that will call `ReactDOM.render` (in React 16+, `ReactDOM.hydrate`) to render a React component into the DOM. The "renderer function" is called at the same time the document ready event would instantate the React components into the DOM.
|
103
102
|
|
104
|
-
Why would you want to call `ReactDOM.hydrate` yourself? One possible use case is [code splitting](
|
103
|
+
Why would you want to call `ReactDOM.hydrate` yourself? One possible use case is [code splitting](docs/outdated/code-splitting.md). In a nutshell, you don't want to load the React component on the DOM node yet. So you want to install some handler that will call `ReactDOM.hydrate` at a later time. In the case of code splitting with server rendering, the server rendered code has any async code loaded and used to server render. Thus, the client code must also fully load any asynch code before server rendering. Otherwise, the client code would first render partially, not matching the server rendering, and then a second later, the full code would render, resulting in an unpleasant flashing on the screen.
|
105
104
|
|
106
|
-
Renderer functions are not meant to be used on the server since there's no DOM on the server. Instead, use a
|
105
|
+
Renderer functions are not meant to be used on the server since there's no DOM on the server. Instead, use a render function. Attempting to server render with a renderer function will throw an error.
|
107
106
|
|
108
107
|
------------
|
109
108
|
|
@@ -113,7 +112,7 @@ Renderer functions are not meant to be used on the server since there's no DOM o
|
|
113
112
|
|
114
113
|
1. [React on Rails docs for react-router](../additional-reading/react-router.md)
|
115
114
|
2. Examples in [spec/dummy/app/views/react_router](../../spec/dummy/app/views/react_router) and follow to the JavaScript code in the [spec/dummy/client/app/startup/ServerRouterApp.jsx](../../spec/dummy/client/app/startup/ServerRouterApp.jsx).
|
116
|
-
3. [Code Splitting docs](
|
115
|
+
3. [Code Splitting docs](docs/outdated/code-splitting.md) for information about how to set up code splitting for server rendered routes.
|
117
116
|
|
118
117
|
------------
|
119
118
|
|
@@ -12,21 +12,27 @@ default: &default
|
|
12
12
|
# public_output_path folder
|
13
13
|
manifest: manifest.json
|
14
14
|
cache_manifest: false
|
15
|
+
|
16
|
+
# Source path is used to check if webpack compilation needs to be run for `compile: true`
|
15
17
|
source_path: client/app
|
16
18
|
|
17
19
|
development:
|
18
20
|
<<: *default
|
19
|
-
#
|
21
|
+
# Generated files for development, in /public/webpack/dev
|
20
22
|
public_output_path: webpack/dev
|
21
23
|
|
22
24
|
test:
|
23
25
|
<<: *default
|
24
|
-
#
|
26
|
+
# Ensure that webpacker invokes webpack to build files for tests if not using the
|
27
|
+
# ReactOnRails rspec helper.
|
28
|
+
compile: true
|
29
|
+
|
30
|
+
# Generated files for tests, in /public/webpack/test
|
25
31
|
public_output_path: webpack/test
|
26
32
|
|
27
33
|
production:
|
28
34
|
<<: *default
|
29
|
-
#
|
35
|
+
# Generated files for production, in /public/webpack/production
|
30
36
|
public_output_path: webpack/production
|
31
37
|
cache_manifest: true
|
32
38
|
```
|
@@ -45,7 +51,7 @@ ReactOnRails.configure do |config|
|
|
45
51
|
# The default is true for development, off otherwise.
|
46
52
|
# With true, you get detailed logs of rendering and stack traces if you call setTimout,
|
47
53
|
# setInterval, clearTimout when server rendering.
|
48
|
-
config.trace = Rails.env.development?
|
54
|
+
config.trace = Rails.env.development? # default
|
49
55
|
|
50
56
|
# Configure if default DOM IDs have a random value or are fixed.
|
51
57
|
# false ==> Sets the dom id to "#{react_component_name}-react-component"
|
@@ -54,62 +60,18 @@ ReactOnRails.configure do |config|
|
|
54
60
|
# it is convenient to set this to true or else you have to either manually set the ids to
|
55
61
|
# avoid collisions. Most newer apps will have only one instance of a component on a page,
|
56
62
|
# so this should be false in most cases.
|
57
|
-
# This value can be
|
58
|
-
config.random_dom_id =
|
59
|
-
|
60
|
-
# defaults to "" (top level)
|
61
|
-
#
|
62
|
-
config.node_modules_location = "client" # Recommended!
|
63
|
-
|
64
|
-
# This configures the script to run to build the production assets by webpack. Set this to nil
|
65
|
-
# if you don't want react_on_rails building this file for you.
|
66
|
-
config.build_production_command = "RAILS_ENV=production bin/webpack"
|
67
|
-
|
68
|
-
################################################################################
|
69
|
-
################################################################################
|
70
|
-
# TEST CONFIGURATION OPTIONS
|
71
|
-
# Below options are used with the use of this test helper:
|
72
|
-
# ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
|
73
|
-
################################################################################
|
74
|
-
|
75
|
-
# If you are using this in your spec_helper.rb (or rails_helper.rb):
|
76
|
-
#
|
77
|
-
# ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
|
78
|
-
#
|
79
|
-
# with rspec then this controls what yarn command is run
|
80
|
-
# to automatically refresh your webpack assets on every test run.
|
81
|
-
#
|
82
|
-
config.build_test_command = "RAILS_ENV=test bin/webpack"
|
83
|
-
|
84
|
-
# Directory where your generated assets go. All generated assets must go to the same directory.
|
85
|
-
# If you are using webpacker, this value will come from your config/webpacker.yml file.
|
86
|
-
# This is the default in webpacker.yml:
|
87
|
-
# public_output_path: packs-test
|
88
|
-
# which means files in /public/packs-test
|
89
|
-
#
|
90
|
-
# Alternately, you may configure this if you are NOT using webpacker. It is relative to your Rails
|
91
|
-
# root directory. A custom, non-webpacker, config might use something like:
|
92
|
-
#
|
93
|
-
# config.generated_assets_dir = File.join(%w[public webpack], Rails.env)
|
94
|
-
# This setting should not be used if using webpacker.
|
63
|
+
# This value can be overridden for a given call to react_component
|
64
|
+
config.random_dom_id = true # default
|
95
65
|
|
96
|
-
#
|
97
|
-
|
98
|
-
# by your config/webpacker.yml soure_path:
|
99
|
-
# source_path: client/app/javascript # if using recommended /client directory
|
100
|
-
#
|
101
|
-
# If you are not using webpacker, the `node_modules_location` is assumed to be the location of your source
|
102
|
-
# files.
|
103
|
-
|
104
|
-
# Define the files we need to check for webpack compilation when running tests.
|
105
|
-
# The default is `%w( manifest.json )` as will be sufficient for most webpacker builds.
|
106
|
-
# However, if you are generated a server bundle that is NOT hashed (present in manifest.json),
|
107
|
-
# then include the file in this list like this:
|
108
|
-
#
|
109
|
-
config.webpack_generated_files = %w( server-bundle.js manifest.json )
|
66
|
+
# defaults to "" (top level)
|
67
|
+
config.node_modules_location = "client" # If using webpacker you should use "".
|
110
68
|
|
111
|
-
#
|
112
|
-
#
|
69
|
+
# This configures the script to run to build the production assets by webpack . Set this to nil
|
70
|
+
# if you don't want react_on_rails building this file for you.
|
71
|
+
# Note, if you want to use this command then you should remove the file
|
72
|
+
# config/webpack/production.js
|
73
|
+
# If that file exists, React on Rails thinks that you'll use the rails/webpacker bin/webpack compiler.
|
74
|
+
config.build_production_command = "RAILS_ENV=production bin/webpack"
|
113
75
|
|
114
76
|
################################################################################
|
115
77
|
################################################################################
|
@@ -127,27 +89,37 @@ ReactOnRails.configure do |config|
|
|
127
89
|
# you should include a name that matches your bundle name in your webpack config.
|
128
90
|
config.server_bundle_js_file = "server-bundle.js"
|
129
91
|
|
92
|
+
# THE BELOW OPTIONS FOR SERVER-SIDE RENDERING RARELY NEED CHANGING
|
93
|
+
#
|
94
|
+
# This value only affects server-side rendering when using the webpack-dev-server
|
95
|
+
# If you are hashing the server bundle and you want to use the same bundle for client and server,
|
96
|
+
# you'd set this to `true` so that React on Rails reads the server bundle from the webpack-dev-server.
|
97
|
+
# Normally, you have different bundles for client and server, thus, the default is false.
|
98
|
+
# Furthermore, if you are not hashing the server bundle (not in the manifest.json), then React on Rails
|
99
|
+
# will only look for the server bundle to be created in the typical file location, typically by
|
100
|
+
# a `webpack --watch` process.
|
101
|
+
# If true, ensure that in config/webpacker.yml that you have both dev_server.hmr and
|
102
|
+
# dev_server.inline set to false.
|
103
|
+
config.same_bundle_for_client_and_server = false
|
104
|
+
|
130
105
|
# If set to true, this forces Rails to reload the server bundle if it is modified
|
131
106
|
# Default value is Rails.env.development?
|
132
|
-
#
|
107
|
+
# You probably will never change this.
|
133
108
|
config.development_mode = Rails.env.development?
|
134
109
|
|
135
|
-
# For server rendering so that
|
110
|
+
# For server rendering so that the server-side console replays in the browser console.
|
136
111
|
# This can be set to false so that server side messages are not displayed in the browser.
|
137
|
-
# Default is true. Be cautious about turning this off.
|
112
|
+
# Default is true. Be cautious about turning this off, as it can make debugging difficult.
|
138
113
|
# Default value is true
|
139
|
-
#
|
140
114
|
config.replay_console = true
|
141
115
|
|
142
116
|
# Default is true. Logs server rendering messages to Rails.logger.info. If false, you'll only
|
143
117
|
# see the server rendering messages in the browser console.
|
144
|
-
#
|
145
118
|
config.logging_on_server = true
|
146
119
|
|
147
120
|
# Default is true only for development? to raise exception on server if the JS code throws for
|
148
121
|
# server rendering. The reason is that the server logs will show the error and force you to fix
|
149
122
|
# any server rendering issues immediately during development.
|
150
|
-
#
|
151
123
|
config.raise_on_prerender_error = Rails.env.development?
|
152
124
|
|
153
125
|
################################################################################
|
@@ -172,6 +144,7 @@ ReactOnRails.configure do |config|
|
|
172
144
|
# Replace the following line to the location where you keep translation.js & default.js for use
|
173
145
|
# by the npm packages react-intl. Be sure this directory exists!
|
174
146
|
# config.i18n_dir = Rails.root.join("client", "app", "libs", "i18n")
|
147
|
+
#
|
175
148
|
# If not using the i18n feature, then leave this section commented out or set the value
|
176
149
|
# of config.i18n_dir to nil.
|
177
150
|
#
|
@@ -179,8 +152,12 @@ ReactOnRails.configure do |config|
|
|
179
152
|
# that will source for automatic generation on translations.js & default.js
|
180
153
|
# By default(without this option) all yaml files from Rails.root.join("config", "locales")
|
181
154
|
# and installed gems are loaded
|
182
|
-
config.i18n_yml_dir = Rails.root.join("config", "locales"
|
155
|
+
config.i18n_yml_dir = Rails.root.join("config", "locales")
|
183
156
|
|
157
|
+
# Possible output formats are js and json
|
158
|
+
# The default format is json
|
159
|
+
config.i18n_output_format = 'json'
|
160
|
+
|
184
161
|
################################################################################
|
185
162
|
################################################################################
|
186
163
|
# CLIENT RENDERING OPTIONS
|
@@ -189,8 +166,47 @@ ReactOnRails.configure do |config|
|
|
189
166
|
################################################################################
|
190
167
|
# default is false
|
191
168
|
config.prerender = false
|
192
|
-
end
|
193
169
|
|
170
|
+
# You can optionally add values to your rails_context. This object is passed
|
171
|
+
# every time a component renders.
|
172
|
+
# See example below for an example definition of RenderingExtension
|
173
|
+
#
|
174
|
+
# config.rendering_extension = RenderingExtension
|
175
|
+
|
176
|
+
################################################################################
|
177
|
+
################################################################################
|
178
|
+
# TEST CONFIGURATION OPTIONS
|
179
|
+
# Below options are used with the use of this test helper:
|
180
|
+
# ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
|
181
|
+
#
|
182
|
+
# NOTE:
|
183
|
+
# Instead of using this test helper, you may ensure fresh test files using rails/webpacker via:
|
184
|
+
# 1. Have `config/webpacker/test.js` exporting an array of objects to configure both client and server bundles.
|
185
|
+
# 2. Set the compile option to true in config/webpacker.yml for env test
|
186
|
+
################################################################################
|
187
|
+
|
188
|
+
# If you are using this in your spec_helper.rb (or rails_helper.rb):
|
189
|
+
#
|
190
|
+
# ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
|
191
|
+
#
|
192
|
+
# with rspec then this controls what yarn command is run
|
193
|
+
# to automatically refresh your webpack assets on every test run.
|
194
|
+
#
|
195
|
+
config.build_test_command = "RAILS_ENV=test bin/webpack"
|
196
|
+
|
197
|
+
# CONFIGURE YOUR SOURCE FILES
|
198
|
+
# The test helper needs to know where your JavaScript files exist. The value is configured
|
199
|
+
# by your config/webpacker.yml source_path:
|
200
|
+
# source_path: client/app # if using recommended /client directory
|
201
|
+
#
|
202
|
+
# Define the files we need to check for webpack compilation when running tests.
|
203
|
+
# The default is `%w( manifest.json )` as will be sufficient for most webpacker builds.
|
204
|
+
# However, if you are generated a server bundle that is NOT hashed (present in manifest.json),
|
205
|
+
# then include the file in this list like this:
|
206
|
+
config.webpack_generated_files = %w( server-bundle.js manifest.json )
|
207
|
+
# Note, be sure NOT to include your server-bundle.js if it is hashed, or else React on Rails will
|
208
|
+
# think the server-bundle.js is missing every time for test runs.
|
209
|
+
end
|
194
210
|
```
|
195
211
|
|
196
212
|
Example of a RenderingExtension for custom values in the `rails_context`:
|
@@ -199,7 +215,7 @@ Example of a RenderingExtension for custom values in the `rails_context`:
|
|
199
215
|
module RenderingExtension
|
200
216
|
|
201
217
|
# Return a Hash that contains custom values from the view context that will get merged with
|
202
|
-
# the standard rails_context values and passed to all calls to
|
218
|
+
# the standard rails_context values and passed to all calls to render functions used by the
|
203
219
|
# react_component and redux_store view helpers
|
204
220
|
def self.custom_context(view_context)
|
205
221
|
{
|
@@ -208,5 +224,3 @@ module RenderingExtension
|
|
208
224
|
end
|
209
225
|
end
|
210
226
|
```
|
211
|
-
|
212
|
-
|