How to quickly start a single-page application with Node.js
2012/04/28 5 Comments
A problem I experienced while starting coding with NodeJS environment and Express framework is that I had difficulties to quickly make a well structured app. I spent too much time on organizing my modules and writing helpers. Paradoxally with Express, I like the fact that I am free to do what I want and don’t encounter too much constraints due to the framework. At last, it was harder to design front end code than back end code.
To deal with that, I used two tools that fit with my requirements :
- CompoundJS : a lightweight framework on top of express. It offers the structure and the vital functions I need to write a good backend and configure express properly.
- Edit : At the time I wrote this article, the project was called RailwayJS, now it’s CompoundJS.
- Brunch : an application assembler to organize and build cleanly my front-end code.
The bad thing with that choice is that there are no out of the box integration. So, in this article, I will give you a way to make them work together and obtain a well structured single page-app in a minute (see the result here). I won’t cover in this article how code is organized, I can just tell you that it is a typical MVC structure for backend and a Backbone MVC for frontend. Look at their documentations for more.
1. Generate files
I assume you have already installed NodeJS. So install needed tools via npm, the node package manager :
npm install compound -g npm install brunch -g
Then generate backend with railway:
compound init blog --coffee cd blog npm install # dependencies installation
With brunch generate frontend after removing frontend stuff from railway:
rm -rf public brunch new client cd client brunch build cd ..
BackboneJS is the MVC framework configured by Brunch by default. If you want to work with AngularJS, you should run the project creation this way :
brunch new client --skeleton https://github.com/scotch/angular-brunch-seed
2. Plug Brunch on Railway
Then configure backend to handle brunch folder instead of old ones. In config/environment.coffee Replace this line :
app.use express.static(cwd + '/public', maxAge: 86400000)
with :
app.use express.static(cwd + '/client/public', maxAge: 86400000)
or for AngularJS case:
app.use express.static(cwd + '/client/_public', maxAge: 86400000)
In base template (index) app/views/layouts/application_layout.ejs , change stylesheet and javascript links :
<%- stylesheet_link_tag('bootstrap', 'style', 'bootstrap-responsive') %>
with
<%- stylesheet_link_tag('app') %>
and
<%- javascript_include_tag('http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', 'bootstrap', 'rails', 'application') %>
with :
<%- javascript_include_tag('vendor', 'app') %>
For AngularJS cas use these lines:
<%- stylesheet_link_tag('css/app') %>
<%- javascript_include_tag('js/vendor', 'js/app') %>
Then clear body to replace it by :
<body> <%- body %> </body>
3. Make entry point and set a route to it
Create a controller to generate an entry point in app/controllers/application_controller.coffee:
action 'index', -> render title: "my single page app"
Then create template file for entry point:
mkdir app/views/application vim app/views/application/index.ejs
fill it with:
<script>require('initialize');</script>
Then add a route to confige/routes.coffee file:
exports.routes = (map) ->
map.get "/", "application#index"
Check that everything is fine by starting server and opening http://localhost:3000/ in your browser (Brunch logo should be displayed):
compound s
4. Use
To make Brunch automatically rebuild you app after each modification, go into the client directory and type:
brunch watch
You can write all your UI code inside client directory. Brunch handles templates too, so don’t worry about writing your html code on client side. Another good thing is that Compound and Brunch offer generators to build your models and controllers faster. Finally, Compound is very efficient for writing REST API : sending and parsing JSON are easy. As you understand, now you have all the stuff you need to build an awesome single-page web application!
Feel free to comment this tutorial and share any thoughts about this.
Wouldn’t it be:
app.use express.static(cwd + ‘/client/build’, maxAge: 86400000)
for the most current version of Brunch?
Thx Benjamin for your comment.
I just try with Brunch 1.1.2 which is a recent one and it creates a “public” folder when I run “brunch build”. Which version do you use ?
I was wrong, Brunch@0.9.1 it seems is what NPM installed.
Really great blog post, I looked at Brunch when I was first looking into Nodejs frameworks and quickly became a fan of railway-js due to a lot of the reasons you highlighted.
Nice job of saving headaches down the road in figuring out how to integrate the two when I have time to get back to really digging into Brunch again.
Great, I am glad it helps you!
I don’t use Railways just Express, but the tip is still very useful. Thanks a lot !