forked from shakacode/react_on_rails
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow component rendering in contexts without requests
allow custom_context even without request added broken test added fixes to allow actionmailer test to pass cleaned up rubocop warnings Update ensure_assets_compiled.rb resolved some reviewed suggestions fix(typo) remove duplicated word in readme updated with proper handles for inMailer added inMailer to test added inMailer checks for test cleaned up rubocop suggestions a few final minor tweaks Fixes typo Update server-rendering-tips.md (shakacode#494) Update server-rendering-tips.md and README.md Update README.md Doc Fixes (shakacode#499) * Update node-server-rendering.md * Update README.md Enhancements to webpack asset preparation * Better messages when creating symlinks * Updated documentation * Enhanced example * Support subdirectories with webpack assets * Move logic for assets code to service object * Using defaults of the env settings or else values for directories and regexp can be provided. Update assets_precompile_spec.rb symlink tests with tempfs Move CONTRIBUTING.MD to project top level This seems to make it show more prominently when making new issues or PRs. Remove Docker from setup * Update .travis.yml * Remove Dockerfile_tests and docker-compose.yml fixed spelling error in readme Update README.md Add support for single digit version strings, closes shakacode#489
- Loading branch information
Showing
44 changed files
with
687 additions
and
298 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,30 @@ | ||
## Node Server Rendering | ||
# Node.js for Server Rendering | ||
|
||
### Warning: this is an experimental feature | ||
Node.js can be used as the backend for server-side rendering instead of [execJS](https://github.com/rails/execjs). Before you try this, consider the tradeoff of extra complexity with your deployments versus *potential* performance gains. We've found that using ExecJS with [mini_racer](https://github.com/discourse/mini_racer) to be "fast enough" so far. That being said, we've heard of other large websites using Node.js for better server rendering performance. | ||
|
||
The default server rendering exploits ExecJS to render react components. | ||
Node server rendering allows you to use separate NodeJS process as a renderer. The process loads your configured server_bundle_js file and | ||
then executes javascript to render the component inside its environment. The communication between rails and node occurs | ||
via socket (`client/node/node.sock`) | ||
If you're serious about this comparing Node.js versus execJS/mini_racer, then [get in touch](mailto:[email protected])! We can definitely collaborate with you on refining this solution. However, please try out these instructions first. | ||
|
||
## Setup of React on Rails with Node.js Server Rendering | ||
**Warning: this is an experimental feature.** | ||
|
||
To do this you need to add a few files and then configure react_on_rails to use NodeJS. Here are the relevant files to add. | ||
|
||
Node server rendering allows you to use separate NodeJS process as a renderer. The process loads your configured server_bundle_js file and then executes javascript to render the component inside its environment. The communication between rails and node occurs | ||
via a socket (`client/node/node.sock`) | ||
|
||
### Getting started | ||
|
||
### Configuration | ||
|
||
#### Update the React on Rails Initializer | ||
|
||
To use node process just set `server_render_method = "NodeJS"` in `config/initializers/react_on_rails.rb`. To change back | ||
to ExecJS set `server_render_method = "ExecJS"` | ||
|
||
### Configuration | ||
```ruby | ||
# app/config/initializers/react_on_rails.rb | ||
config.server_render_method = "NodeJS" | ||
``` | ||
|
||
You need to configure the name of the server bundle in two places: | ||
|
||
|
@@ -26,3 +38,109 @@ You need to configure the name of the server bundle in two places: | |
# not affect performance. | ||
config.server_bundle_js_file = "webpack-bundle.js" | ||
``` | ||
|
||
And in `client/node/package.json` | ||
|
||
```javascript | ||
// client/node/package.json | ||
{ | ||
"name": "react_on_rails_node", | ||
"version": "0.0.0", | ||
"private": true, | ||
"scripts": { | ||
"start": "node ./server.js -s webpack-bundle.js" | ||
}, | ||
"dependencies": { | ||
} | ||
} | ||
``` | ||
|
||
And you'll need this file: `client/node/server.js` | ||
|
||
```javascript | ||
// client/node/server.js | ||
var net = require('net'); | ||
var fs = require('fs'); | ||
|
||
var bundlePath = '../../app/assets/webpack/'; | ||
var bundleFileName = 'webpack-bundle.js'; | ||
|
||
var currentArg; | ||
|
||
function Handler() { | ||
this.queue = []; | ||
this.initialized = false; | ||
} | ||
|
||
Handler.prototype.handle = function (connection) { | ||
var callback = function () { | ||
connection.setEncoding('utf8'); | ||
connection.on('data', (data)=> { | ||
console.log('Processing request: ' + data); | ||
var result = eval(data); | ||
connection.write(result); | ||
}); | ||
}; | ||
|
||
if (this.initialized) { | ||
callback(); | ||
} else { | ||
this.queue.push(callback); | ||
} | ||
}; | ||
|
||
Handler.prototype.initialize = function () { | ||
console.log('Processing ' + this.queue.length + ' pending requests'); | ||
var callback; | ||
while (callback = this.queue.pop()) { | ||
callback(); | ||
} | ||
|
||
this.initialized = true; | ||
}; | ||
|
||
var handler = new Handler(); | ||
|
||
process.argv.forEach((val) => { | ||
if (val[0] == '-') { | ||
currentArg = val.slice(1); | ||
return; | ||
} | ||
|
||
if (currentArg == 's') { | ||
bundleFileName = val; | ||
} | ||
}); | ||
|
||
try { | ||
fs.mkdirSync(bundlePath); | ||
} catch (e) { | ||
if (e.code != 'EEXIST') throw e; | ||
} | ||
|
||
fs.watchFile(bundlePath + bundleFileName, (curr) => { | ||
if (curr && curr.blocks && curr.blocks > 0) { | ||
if (handler.initialized) { | ||
console.log('Reloading server bundle must be implemented by restarting the node process!'); | ||
return; | ||
} | ||
|
||
require(bundlePath + bundleFileName); | ||
console.log('Loaded server bundle: ' + bundlePath + bundleFileName); | ||
handler.initialize(); | ||
} | ||
}); | ||
|
||
var unixServer = net.createServer(function (connection) { | ||
handler.handle(connection); | ||
}); | ||
|
||
unixServer.listen('node.sock'); | ||
|
||
process.on('SIGINT', () => { | ||
unixServer.close(); | ||
process.exit(); | ||
}); | ||
|
||
``` | ||
|
Oops, something went wrong.