toString: support rehydration
This commit is contained in:
@@ -21,6 +21,7 @@ productive package.
|
||||
- [keyboard](#keyboard)
|
||||
- [websockets](#websockets)
|
||||
- [Rendering in Node](#rendering-in-node)
|
||||
- [Rehydration](#rehydration)
|
||||
- [API](#api)
|
||||
- [FAQ](#faq)
|
||||
- [Installation](#installation)
|
||||
@@ -310,9 +311,10 @@ queueing data. You might want to use a package from `npm` or [write your
|
||||
own][ws-reconnect] if you're building something for production.
|
||||
|
||||
## Rendering in Node
|
||||
Sometimes it's necessary to render code inside of Node; for serving first
|
||||
requests, testing or other purposes. Applications that are capable of being
|
||||
rendered in both Node and the browser are called _[isomorphic][isomorphic]_.
|
||||
Sometimes it's necessary to render code inside of Node; for serving hyper fast
|
||||
first requests, testing or other purposes. Applications that are capable of
|
||||
being rendered in both Node and the browser are called
|
||||
_[isomorphic][isomorphic]_.
|
||||
|
||||
Rendering in Node is slightly different than in the browser. First off, to
|
||||
maintain performance all calls to `subscriptions`, `effects`, and `reducers`
|
||||
@@ -352,6 +354,45 @@ if (module.parent) module.exports = app
|
||||
else document.body.appendChild(app.start())
|
||||
```
|
||||
|
||||
### Rehydration
|
||||
Now that your application is succesfully rendering in Node, the next step would
|
||||
be to make it load a JavaScript bundle once has loaded the HTML. To do this we
|
||||
will use a technique called _rehydration_.
|
||||
|
||||
_Rehydration_ is when you take the static, server-rendered version of your
|
||||
application (static HTML, _dehydrated_ because it has no logic) and _rehydrate_
|
||||
it by booting up the JS and attaching event handlers on the DOM to make it
|
||||
dynamic again. It's like restoring flavor to cup noodles by adding hot water.
|
||||
|
||||
Because we're using something called `morphdom` under the hood, all we need is
|
||||
point at an `id` at the root of the application. The syntax for this is
|
||||
slightly different from what we've seen so far, because we're _updating_ a
|
||||
dehydrated DOM nodes to make them dynamic, rather than a new DOM tree and
|
||||
attaching it to the DOM.
|
||||
```js
|
||||
const choo = require('choo')
|
||||
const app = choo()
|
||||
|
||||
app.router((route) => [
|
||||
route('/', (params, state, send) => choo.view`
|
||||
<h1 id="app-root">${state.message}</h1>
|
||||
`)
|
||||
])
|
||||
|
||||
if (module.parent) module.exports = app
|
||||
else app.start('#app-root'))
|
||||
```
|
||||
|
||||
When the JS is booted on top of the dehydrated application, it will look for
|
||||
the `#app-root` id and load on top of it. You can choose any name you like for
|
||||
the id, but __make sure it's the same on every possible top level DOM node__,
|
||||
or else things might break. Furthermore to ensure things go smoothly, try and
|
||||
keep the initial state identical on both the server and the client.
|
||||
|
||||
And that's it! If you want to go down the route of mad performance, consider
|
||||
make all first request static and caching them using something like [bl][bl],
|
||||
[nginx][nginx], [varnish][varnish] or a global CDN.
|
||||
|
||||
## API
|
||||
### app = choo()
|
||||
Create a new `choo` app
|
||||
@@ -404,7 +445,7 @@ for the past year. I originally used `virtual-dom` with `virtual-app` and
|
||||
`wayfarer` where now it's `yo-yo` with `send-action` and `sheet-router`. The
|
||||
main benefit of using `choo` over these technologies separately is that it
|
||||
becomes easier for teams to pick up and gather around. The code base for `choo`
|
||||
itself is super petite (`~150` LOC) and mostly acts to enforce structure around
|
||||
itself is super petite (`~200` LOC) and mostly acts to enforce structure around
|
||||
some excellent npm packages. This is my take on modular frameworks; I hope
|
||||
you'll find it pleasant.
|
||||
|
||||
@@ -535,3 +576,6 @@ $ npm install choo
|
||||
[module-parent]: https://nodejs.org/dist/latest-v6.x/docs/api/modules.html#modules_module_parent
|
||||
[sse-reconnect]: http://stackoverflow.com/questions/24564030/is-an-eventsource-sse-supposed-to-try-to-reconnect-indefinitely
|
||||
[ws-reconnect]: http://stackoverflow.com/questions/13797262/how-to-reconnect-to-websocket-after-close-connection
|
||||
[bl]: https://github.com/rvagg/bl
|
||||
[varnish]: https://varnish-cache.org
|
||||
[nginx]: http://nginx.org/
|
||||
|
||||
Reference in New Issue
Block a user