Node.js Web App
CRASH COURSE
By Aaron Silverman, Code Slinger at Video BlocksMarch 19, 2014
Note: node.js is getting more and more popular every year!
Node.js - download and install it!
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Worldn');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Create simple server web server
server.js
Run simple web server
$ node server.js
Server running at http://127.0.0.1:1337/
Connect to simple web server
Why reinvent the wheel?
Packages FTW!
$ npm install -g express-generator
...
express-generator@3.0.0
/usr/local/lib/node_modules/express-generator
├── mkdirp@0.3.5
└── commander@1.3.2 (keypress@0.1.0)
Create skeleton web application
$ express --ejs myapp
...
create : myapp
...
install dependencies:
...
run the app:
Install dependencies
$ cd myapp
$ npm install
…
express@3.4.8 node_modules/express
...
Start web application
$ npm start
> application-name@0.0.1 start
/Users/aaron/Workspace/upenn/myapp
> node ./bin/www
Connect to web application
What’s going on?
automagically created folders and files
package.json is key
started by npm start
installed by npm install
require - import/include other files
and packages
imports debug package
imports app file
what is exported
Middleware Magic
view engine
modules
middleware
routing
Route handlers
render view
View - Embedded JavaScript
view variable
Spice up our root page - route handler
exports.index = function(req, res){
res.render('index', { title: 'Express' });
res.render('index', {title: 'Express', name: 'Aaron'});
};
routes/index.js
Spice up our root page - view
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<p>&ldquo;Welcome to <%= title %>&rdquo;</p>
<p>&mdash; <%= name %><p>
</body>
views/index.ejs
Restart and connect
$ npm start
Internet folks love cats
Cat image
image file
Cat view
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>Cat</h1>
<img src="/images/cat.jpg" />
</body>
</html>
views/cat.ejs
Cat route handler
exports.index = function(req, res) {
res.render('index', {title: 'Penn', name: 'Aaron'});
};
exports.cat = function(req, res) {
res.render('cat');
}
routes/index.js
Cat route
app.get('/', routes.index);
app.get('/users', users.list);
app.get('/cat', routes.cat);
app.js
Enough manual restarting - nodemon
$ sudo npm install -g nodemon
...
nodemon@1.0.15
…
Tell nodemon what to run
"scripts": {
"start": "node ./bin/www"
},
"main": "bin/www",
"dependencies": {
package.json
Start server using nodemon
$ nodemon
[nodemon] v1.0.15
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node bin/www`
Navigate to cat page
Name that cat
Name that cat - route handler
exports.cat = function(req, res) {
var name = req.param('name','Mr. Cat');
res.render('cat');
res.render('cat', {name: name});
}
routes/index.js
Name that cat - view
<body>
<h1>Cat</h1>
<h1>Meet <%= name %>, the Cat.</h1>
<img src="/images/cat.jpg" />
</body>
routes/index.js
Revisit cat page
Pass name in query parameter
Moar Cats!
Twitter Bootstrap - CSS for dummies
Bootstrap grid and components
CSS classes also makes special components
CSS class “row” starts row of a 12 column grid
CSS class “col-md-N” starts a responsive N-column wide grid element
Note: rows can be nested inside columns for a nested grid
Cat view - bootstrap css/js
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" />
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
…
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
</html>
views/cat.ejs
Note: instead of using external assets we could also have downloaded and extracted these files into the
public/stylesheets and public/javscripts directories.
Cat view - name jumbotron
<body>
<div class="jumbotron">
<h1>Meet <%= name %>, the Cat.</h1>
<p>Best cat in the land</p>
</div>
views/cat.ejs
Cat view - cat grid
<div class="container cat-grid">
<div class="row">
<div class="col-md-4">
<img src="/images/cat.jpg" />
</div>
<div class="col-md-4">
...
</div>
<div class="col-md-4">
<img src="/images/cat.jpg" />
</div>
</div>
</div>
views/cat.ejs
<div class="row">
<div class="col-md-6">
<img src="/images/cat.jpg" />
</div>
<div class="col-md-6">
<img src="/images/cat.jpg" />
</div>
</div>
<div class="row">
<div class="col-md-6">
<img src="/images/cat.jpg" />
</div>
<div class="col-md-6">
<img src="/images/cat.jpg" />
</div>
</div>
Cat view - cat style
.cat-grid img {
height: 100px;
}
public/stylesheets/style.css
Moar, responsive, cats
Module Time
Npm install and save
$ npm install --save express-partials
npm http GET https://registry.npmjs.org/express-partials
npm http 304 https://registry.npmjs.org/express-partials
express-partials@0.2.0 node_modules/express-partials
Added to package.json
newly installed package
Use new middleware
var bodyParser = require('body-parser');
var partials = require('express-partials');
var routes = require('./routes');
var users = require('./routes/user');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(partials());
app.use(favicon());
app.js
Create common view layout
views/layout.ejs
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" />
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<%- body %>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
</html>
Clean up cat view
views/cat.ejs
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" />
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
…
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
</html>
Clean up index view
views/index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
…
</body>
</html>
Revisit Pages
$ nodemon
How can Grandma see the cat?
Deploy on the interwebs!
Transfer code to your server
$ scp -i ~/.ssh/macbookair.pem -r myapp/ ubuntu@ec2-23-
20-153-76.compute-1.amazonaws.com:~/
Note: Ideally your code is checked into a source control repository such as git, and you would
add your server’s public key to be allowed to access to the repository.
Then you would do something like:
$ ssh -i .ssh/macbookair.pem ubuntu@ec2-23-20-153-76.compute-1.amazonaws.com
$ git clone git@github.com:Username/myapp.git
Install node.js on your server
$ ssh -i .ssh/macbookair.pem ubuntu@ec2-23-20-153-76.
compute-1.amazonaws.com
$ sudo apt-get install python-software-properties
$ sudo apt-add-repository ppa:chris-lea/node.js
$ sudo apt-get update
$ sudo apt-get install nodejs
$ node --version
v0.10.26
Install dependencies
$ cd myapp
$ npm install
Note: If you transferred your node_modules folder (such as scp did in this presentation) this won’t be
necessary. However typically that folder should be ignored by version control (e.g. in .gitignore) and you
will have to do this step.
Allow HTTP traffic for the server
Allow port forwarding to listen port
$ sudo vim /etc/sysctl.conf
(uncomment net.ipv4.ip_forward)
$ sudo sysctl -p /etc/sysctl.conf
net.ipv4.ip_forward = 1
$ sudo iptables -A PREROUTING
-t nat -i eth0 -p tcp --dport 80 -j
REDIRECT --to-port 3000
Start and connect to server
$ npm start
> application-name@0.0.1 start
/home/ubuntu/myapp
> node ./bin/www
Forever - run node as a daemon
$ sudo npm install -g forever
…
forever@0.10.11 /usr/lib/node_modules/forever
…
$ forever start bin/www
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it
does not stay up for at least 1000ms
info: Forever processing file: bin/www
Website now live forever!
Node.js & Twitter Bootstrap Crash Course

Node.js & Twitter Bootstrap Crash Course

  • 1.
    Node.js Web App CRASHCOURSE By Aaron Silverman, Code Slinger at Video BlocksMarch 19, 2014
  • 2.
    Note: node.js isgetting more and more popular every year! Node.js - download and install it!
  • 3.
    var http =require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); Create simple server web server server.js
  • 4.
    Run simple webserver $ node server.js Server running at http://127.0.0.1:1337/
  • 5.
  • 7.
    Why reinvent thewheel? Packages FTW! $ npm install -g express-generator ... [email protected] /usr/local/lib/node_modules/express-generator ├── [email protected] └── [email protected] ([email protected])
  • 8.
    Create skeleton webapplication $ express --ejs myapp ... create : myapp ... install dependencies: ... run the app:
  • 9.
    Install dependencies $ cdmyapp $ npm install … [email protected] node_modules/express ...
  • 10.
    Start web application $npm start > [email protected] start /Users/aaron/Workspace/upenn/myapp > node ./bin/www
  • 11.
    Connect to webapplication
  • 13.
    What’s going on? automagicallycreated folders and files
  • 14.
    package.json is key startedby npm start installed by npm install
  • 15.
    require - import/includeother files and packages imports debug package imports app file what is exported
  • 16.
  • 17.
  • 18.
    View - EmbeddedJavaScript view variable
  • 19.
    Spice up ourroot page - route handler exports.index = function(req, res){ res.render('index', { title: 'Express' }); res.render('index', {title: 'Express', name: 'Aaron'}); }; routes/index.js
  • 20.
    Spice up ourroot page - view <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <p>&ldquo;Welcome to <%= title %>&rdquo;</p> <p>&mdash; <%= name %><p> </body> views/index.ejs
  • 21.
  • 23.
  • 24.
  • 25.
    Cat view <!DOCTYPE html> <html> <head> <linkrel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1>Cat</h1> <img src="/images/cat.jpg" /> </body> </html> views/cat.ejs
  • 26.
    Cat route handler exports.index= function(req, res) { res.render('index', {title: 'Penn', name: 'Aaron'}); }; exports.cat = function(req, res) { res.render('cat'); } routes/index.js
  • 27.
    Cat route app.get('/', routes.index); app.get('/users',users.list); app.get('/cat', routes.cat); app.js
  • 28.
    Enough manual restarting- nodemon $ sudo npm install -g nodemon ... [email protected]
  • 29.
    Tell nodemon whatto run "scripts": { "start": "node ./bin/www" }, "main": "bin/www", "dependencies": { package.json
  • 30.
    Start server usingnodemon $ nodemon [nodemon] v1.0.15 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node bin/www`
  • 31.
  • 33.
  • 34.
    Name that cat- route handler exports.cat = function(req, res) { var name = req.param('name','Mr. Cat'); res.render('cat'); res.render('cat', {name: name}); } routes/index.js
  • 35.
    Name that cat- view <body> <h1>Cat</h1> <h1>Meet <%= name %>, the Cat.</h1> <img src="/images/cat.jpg" /> </body> routes/index.js
  • 36.
  • 37.
    Pass name inquery parameter
  • 39.
  • 40.
    Twitter Bootstrap -CSS for dummies
  • 41.
    Bootstrap grid andcomponents CSS classes also makes special components CSS class “row” starts row of a 12 column grid CSS class “col-md-N” starts a responsive N-column wide grid element Note: rows can be nested inside columns for a nested grid
  • 42.
    Cat view -bootstrap css/js <head> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" /> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> … <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> </body> </html> views/cat.ejs Note: instead of using external assets we could also have downloaded and extracted these files into the public/stylesheets and public/javscripts directories.
  • 43.
    Cat view -name jumbotron <body> <div class="jumbotron"> <h1>Meet <%= name %>, the Cat.</h1> <p>Best cat in the land</p> </div> views/cat.ejs
  • 44.
    Cat view -cat grid <div class="container cat-grid"> <div class="row"> <div class="col-md-4"> <img src="/images/cat.jpg" /> </div> <div class="col-md-4"> ... </div> <div class="col-md-4"> <img src="/images/cat.jpg" /> </div> </div> </div> views/cat.ejs <div class="row"> <div class="col-md-6"> <img src="/images/cat.jpg" /> </div> <div class="col-md-6"> <img src="/images/cat.jpg" /> </div> </div> <div class="row"> <div class="col-md-6"> <img src="/images/cat.jpg" /> </div> <div class="col-md-6"> <img src="/images/cat.jpg" /> </div> </div>
  • 45.
    Cat view -cat style .cat-grid img { height: 100px; } public/stylesheets/style.css
  • 46.
  • 48.
  • 49.
    Npm install andsave $ npm install --save express-partials npm http GET https://registry.npmjs.org/express-partials npm http 304 https://registry.npmjs.org/express-partials [email protected] node_modules/express-partials
  • 50.
    Added to package.json newlyinstalled package
  • 51.
    Use new middleware varbodyParser = require('body-parser'); var partials = require('express-partials'); var routes = require('./routes'); var users = require('./routes/user'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(partials()); app.use(favicon()); app.js
  • 52.
    Create common viewlayout views/layout.ejs <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" /> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <%- body %> <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> </body> </html>
  • 53.
    Clean up catview views/cat.ejs <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" /> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> … <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> </body> </html>
  • 54.
    Clean up indexview views/index.ejs <!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> … </body> </html>
  • 55.
  • 57.
    How can Grandmasee the cat?
  • 58.
    Deploy on theinterwebs!
  • 59.
    Transfer code toyour server $ scp -i ~/.ssh/macbookair.pem -r myapp/ ubuntu@ec2-23- 20-153-76.compute-1.amazonaws.com:~/ Note: Ideally your code is checked into a source control repository such as git, and you would add your server’s public key to be allowed to access to the repository. Then you would do something like: $ ssh -i .ssh/macbookair.pem [email protected] $ git clone [email protected]:Username/myapp.git
  • 60.
    Install node.js onyour server $ ssh -i .ssh/macbookair.pem ubuntu@ec2-23-20-153-76. compute-1.amazonaws.com $ sudo apt-get install python-software-properties $ sudo apt-add-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs $ node --version v0.10.26
  • 61.
    Install dependencies $ cdmyapp $ npm install Note: If you transferred your node_modules folder (such as scp did in this presentation) this won’t be necessary. However typically that folder should be ignored by version control (e.g. in .gitignore) and you will have to do this step.
  • 62.
    Allow HTTP trafficfor the server
  • 63.
    Allow port forwardingto listen port $ sudo vim /etc/sysctl.conf (uncomment net.ipv4.ip_forward) $ sudo sysctl -p /etc/sysctl.conf net.ipv4.ip_forward = 1 $ sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
  • 64.
    Start and connectto server $ npm start > [email protected] start /home/ubuntu/myapp > node ./bin/www
  • 65.
    Forever - runnode as a daemon $ sudo npm install -g forever … [email protected] /usr/lib/node_modules/forever … $ forever start bin/www warn: --minUptime not set. Defaulting to: 1000ms warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms info: Forever processing file: bin/www
  • 66.