hapi-riot
Render Riot Components Server-side in your Hapi.js Web Application.
(supports progressive enhancement on the client so it Works Everywhere All The TimeTM)
Why?
We love the simplicity of Riot.js.
Riot has the "features" we need and none of the complexity we don't want.
Riot's clean syntax results in components with less code than other
"View Libraries" or "Frameworks" see: http://riotjs.com/compare/
Writing less code means you (the developer/designer) get more done,
have less to maintain and the people using your app
have to download fewer bytes thus saves time/bandwidth.
It's a win-win for everyone.
Why Server-Side Rendering Matters ?
If you render your app on the client/device at least
1% of your people will see a blank page (no app).
The people who won't see your app are your potential users/customers who
for one reason or another don't have the latest device/browser,
don't have the most reliable internet connection
or have dissabled JavaScript in their browser for security reasons.
The Page Loads Faster...
Pages rendered on the server can send the absolute minimum markup to the client.
This means the "time to first paint" is always faster than loading a client-side framework
and rendering a page on the client. So, your app/site is and feels faster to people.
Why aren't all apps built this way?
Good question! Most developers are lazy. They deny the existence of
older browsers/devices as the "minority" convinced that it's "more work"
than they need to do.
We are on a quest to change the perception that universal rendering is
"more difficult" and help people write code that Works Everywhere All The TimeTM
Read More
What?
Server-side rendering of Riot Components using the Vision Plugin.
Note if you are totally new to Hapi.js see:
https://github.com/dwyl/learn-hapi
And/or if you are new to Riot.js check out:
https://github.com/dwyl/learn-riot
How?
Install
npm install hapi vision hapi-riot --save
Use it
server.register(Vision, (err) => {
if (err) {
console.log('Failed to load vision.');
}
server.views({
engines: {
tag: require('hapi-riot')
},
relativeTo: __dirname,
path: 'views'
});
server.route({
method: 'GET',
path: '/',
handler: (request, reply) => {
reply.view('index', { title: 'My Amazing Title!');
}
});
}
Note: More/Complete examples are in the /examples
directory.
If you stuck or need any help just ask! https://github.com/dwyl/hapi-riot/issues
Optional compileOptions
(That Simplify Your Life!)
We have added a few features to simplify our own projects.
These are documented below, but are not meant to be fit for everyone.
None are enabled by default so if you "just" want to render simple
Riot Components as your Hapi Views, follow the simple example.
doctype
(default)
Riot does not like it when you include "unbalanced" tags.
So, instead of manually including the DOCTYPE
declaration at the top
of your tag it gets "injected" at the top of the rendered view
by hapi-riot
.
removeCache
While you are developing your app you typically don't want
your views to be cached, however, when you deploy your app
by setting NODE_ENV=production
views will be cached.
If for any reason you want to cache your views during development,
or if you need to debug production on your localhost,
set the compileOptions.removeCache: false
like this:
server.views({
engines: {
tag: require('hapi-riot')
},
relativeTo: __dirname,
path: 'views',
compileOptions: {
removeCache: false
}
});
Lessons Learned & "Gotchas"
1. Don't leave tag files empty!
e.g: if you create a new tag views/bye.tag
and forget to
write some html
code inside it you will see a stranage error
when you attempt to render it or any other existing tag!
When you create a new tag add something to it immediately. e.g: views/bye.tag
<bye>
<h1> Goodbye {opts.name}! </h1>
</bye>
If you leave a tag empty you will see a strange error.
2. console.log
in your .tag
file ...
(This is fairly obvious, once you think about it)
if you write a console.log('your message')
and render it on the server,
it will log out in your server's stdout
(i.e. your terminal).