Chalice - The Holy Grail
Documentation Site for Chalice
node installed first. After that you can run:
npm install -g grunt-cli npm install sudo easy_install-2.7 Pygments grunt open http://localhost:3000
What is the holy grail of web development?
I'm sure everyone has a different view but heres mine:
- Share code across the client/server seamlessly
- Boot application on the server to generate the html
- Boot application on client to progressively enhance
- Dont block the critical rendering path to break the 1s time to glass barrier
- Snappy Jank Free Applications
- 100/100 page speed
And for development:
- CoffeeScript + SourceMap debugging
npmfor package management
- Rebuild on file change (selectively rebuild js or css when source files change)
live-reloadout of the box
- Not implemented yet: Stylus Source Maps
for debugging in chrome dev tools.
String Concatenation and Dom Creation Speed
Dom creation libraries are getting faster. But the clear winner is still concatenating strings. This also makes it easier to work with views on the server.
Don't block rendering path and Progressive Enhancement Speed Gains
I'm pretty opinionated with my CommonJS dependencies here but it just makes sense
if the end goal is to get Backbone running on the server. My approach is
to provide a thin layer on top of Backbone that allows it to run fast
and seamless inside
node.js. The templates are handlebars and the
language is coffeescript. This approach differs from rendr in
that I'm not rewriting the routing layer. Simply overwriting
Backbone.Router::route to make an express route and call the same
route on the server. Something like:
Backbone.Router::route = (route, name) -> app.get '/' + route, (req, res) => @[name] _.values(req.params)
This leaves the
MV* implementation up to the developer.
The backbone docs say it best:
References between Models and Views can be handled several ways. Some people like to have direct pointers, where views correspond 1:1 with models (model.view and view.model). Others prefer to have intermediate "controller" objects that orchestrate the creation and organization of views into a hierarchy. Others still prefer the evented approach, and always fire events instead of calling methods directly. All of these styles work well.
How The View Works
_ensureElement to try to first get the element
out of the DOM. Calling super wont create anything if
@el is defined but when
it isn't it will create the element using jQuery. This method does nothing on
_ensureElement: -> if Backbone.$? @el = @getElFromDom() super
When calling render on the view, on the server it will return a wrapped
string, and on the client side it will return
this as usual.
render: -> unless @$el?.html @toHTML(no) return @toHTML(yes) @afterRender() this
View = require 'chalice-view' view = new View # client side view.render() => view object # server side view.render() => '<div class=\'view\' data-cid=\'view1\' ></div>'
semantic.gs is used as well as media queries to get some pretty nice syntax for layout:
// device media queries tablet = "(min-width: 768px) and (max-width: 979px)" phone = "(max-width: 767px)" // layout .navbar-view row() nav > a column(2) @media phone column(12)
The Grunt Build System
Grunt is becoming a popular build tool, and for good reason. If you
haven't seen grunt before, check the getting started guide. Running
grunt out of the box will give you a dev server on
that will selectively rebuild and livereload in the browser when
.styl files change.
grunt- Alias for "default" task
grunt default- Alias for "clean", "stylus:dev", "browserify2:dev", "express:app", "livereload-start", "regarde" tasks.
grunt build- Alias for "clean", "stylus:build", "browserify2:build".
grunt serve- Alias for "express:app", "express-keepalive" tasks.
grunt clean- Clean files and folders.
grunt devtools- A GUI For grunt in chrome devtools
You can use the following grunt tasks to generate new views/models/routers:
grunt generate:view --name=MyView
grunt generate:model --name=MyModel
grunt generate:router --name=MyRouter
grunt delete:view --name=MyView
grunt delete:model --name=MyModel
grunt delete:router --name=MyRouter
$ grunt generate:router --name=MyRouter Running "generate:router" (generate) task File written to: ./src/routers/myrouter.coffee File written to: ./test/routers/myrouter.coffee Done, without errors. $ grunt delete:router --name=MyRouter Running "delete:router" (delete) task File deleted: ./src/routers/myrouter.coffee File deleted: ./test/routers/myrouter.coffee Done, without errors.
You can get a list of all the tasks by running
Parts of the Library
The libraries live on
npm and github.