Skip to content

lecaoquochung/nodejs-example

Repository files navigation

nodejs

NAVIGATION

  • GET STARTED
  • PROJECT ARCHITECTURE
  • ASSETS
  • MVC DEVELOPING LAYERs
  • MONGODB (MANAGING USER)
  • EXAMPLE FUNCTIONs
  • EXPRESS BASIC FORM
  • EXPRESS BLOG SYSTEM
  • USER LOGIN SYSTEM
  • SOCKET.IO BASIC
  • SOCKET.IO CHAT
  • MEAN.JS BASIC
  • MOVIE SYSTEM WITH KRAKEN
  • EXAMPLE APP: INSTAGRAM LIKE
  • COUCHDB BASIC
  • REFERENCE
  • API
  • ENVIRONMENT SETUP
  • TDD

GET STARTED

Install NPM (Nodejs package management) & dependencies

  • Install NPM
sudo yum install nodejs // sudo apt-get install nodejs
sudo yum install npm // sudo apt-get install npm
// update to latest npm

sudo npm install -g n // nodejs verison stable
sudo n 4.4.7 # install node ver 4.4.7 

// update version on nodejs
sudo npm install npm@latest -g
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
  • Install Bower
npm install -g bower
  • Install Gulp
sudo npm install -g gulp

Hello World

Modules (Define & Use)

  • Encapsulate in its own file
// code.js
exports.project = 'Nodejs';
exports.coding = function() {
  console.log('I am coding ' + exports.project);
}

PROJECT ARCHITECTURE

Nodejs application basic layers

Task runner & building system

  • Grunt (init & sample)
  • configuration file: gruntfile.js
  • write to file
npm install -g grunt-cli
npm install grunt-contrib-concat --save
npm install grunt-contrib-watch grunt-contrib-uglify --save // update package.json
npm install -g gulp
npm install gulp-concat gulp-uglify gulp-rename --save
npm install gulp-uglify --save
npm install gulp-rename --save

gulp sample

Test-driven development

  • Benefit
  • Stability application
  • Automated testing saves time -> improving & refactoring more
  • Better structuring & modular approachs
  • Continuous test -> dev new features on existing app, Automated test -> know what code breaks an old feature
  • test -> document (new members join the team) test driven flow
  • Mocha
  • sample/mocha.js read external JSON files
npm install mocha -g
mocha sample/mocha.js

mocha test

MVC Pattern

REST(Representational State Transfer) API Concept

  • REST API benefit: simple & highly scalable
  • Example scenario: Manage online store users
  • GET /users -> return list of users
  • POST /users -> create new users
  • PUT /users/[id] -> edit the user data with user id
  • DELETE /users/[id] -> delete user with user id
# sample/server_restapi.js
# curl http://localhost:1337/ // GET
# curl -X PUT -d item="Nodejs Example" http://localhost:1337/ // PUT
# curl -X PUT -d item="Udon" http://localhost:1337 // PUT with query process server_restapi_query

ASSETS

Serving files

  • Write everything for server to handle incoming request (Not server automatically like Linux-Apache-MySQL-PHP)
  • Example of assets function (server image, css, Javascript)
// native modules
var http = require('http');
var fs = require('fs');
var path = require('path');

// assets module
var files = { };
var port = 9000;
var host = '127.0.0.1';

var assets = function(req,res){
  // ...
};

var app = http.createServer(assets).listen(port, host);
console.log('Listening on ' + host + ":" + port);

  • Assets functions
  • Check file exists (HTTP error code)
var sendError = function(message, code) {...});
  • Recognize files & its extension
  • Sending files content to browser (Content-Type included)
  • Ex: sample/assets_functions.js

CSS processing

Javascript Client-Side packing

  • Goal: serving only 1 JavaScript file to the client's browser (Node.js cand do with tools)
  • Tools to do
  • Gulp (Concatenate files)
  • RequireJS (Modularity in the browser): Encapsulate client-side js into 1 file (?: need some examples)
npm install -g requirejs

// in code_requirejs folder
r.js -o build.js
  • Browsersify (Node.js -> Browser)
  • Sovle module problem
require(['modules/ajax', 'modules/router'], function(ajax, router) {
 ...
});

// better with browserify
var ajax = require('modules/ajax');
var router = require('modules/router');
// Install
npm install -g browserify

// defaul sample/browserify
browserify ./main.js -o main-built.js

HTML Template

<script type="text/x-handlebars" id="my-template">
 <p>Hello, <strong> </strong>!</p>
</script>

Since the tag has an id attribute, we can get its content easily in the following way:
var template = document.querySelector('#my-template').innerHTML;
  • Loading template external (complex)
// like jquery method
$.get('/templates/template.html', function(html) {
 // ...
});
<script type="text/jsx">
  var HelloMessage = React.createClass({
    render: function() {
      // Note: the following line is invalid JavaScript,
      // and only works using React parser.
      return <div>Hello {this.props.name}</div>;
    }
  });
</script>
There are solutions that do not have templates in the form of HTML. There
are tools that use templates written in JSON or YAML. For example, AbsurdJS
(http://absurdjs.com/) can keep its template inside the JavaScript class
definition as follows:

body: {
 'section.content#home': {
 nav: [
 { 'a[href="#" class="link"]': 'A' },
 { 'a[href="#" class="link"]': 'B' },
 { 'a[href="#" class="link"]': 'C' }
 ]
 },
 footer: {
 p: 'Text in the Footer'
 }
}
  • Precompiling tempaltes (fast for Backend)
  • Do not need to think about HTML Template
  • Separated from Javascript
  • Do not need to fetch & process HTML
"ractive": "0.6.1",
"gulp-tap": "0.1.3"

MVC DEVELOPING LAYERs 20160725

  • File structure
  • Backend & Frontend Router
  • Rative.js(client-side framework if needed)
  • Application main file
  • MVC Classes

Directory structure

  • nodejs-example structure example MVC structure
  • Backend folder
  • Node.js environment

Server handlers

  • Server handlers
var app = http.createServer(assets).listen(port, '127.0.0.1');
  • API handler: client-side communicate with the backend via REST API
  • Page handlers: not API request -> server HTML page
  • ractive.js: Framework for client-side
  • frontend/app.j: client-side Javascript

Router

  • Path frontend/lib/Router.js (Default route: skip parameter & register function match every route)
  • Router.js check function can be used in both nodejs & client-side javascript.
  • Problem: check function (string-to-string matching -> need to support dynamic parameters like :id ...)
/home: This matches http://localhost/home
/user/feed: This matches http://localhost/user/feed
/user/:id/profile: This matches http://localhost/user/45/profile
/user/:id/:action: This matches http://localhost/user/45/update
  • Server & Client router (?: Common & non-common problem -> )

Ractive.js

  • Developed by TheGuardian
  • DOM interaction & 2-way data binding & custom component creation.
  • Ractive.js uses mustache (http://mustache.github.io/) as a template language

Application entry point

// frontend/js/app.js
var Router = require('./lib/Router')();
var Home = require('./controllers/Home');
var currentPage;
var body;

var showPage = function(newPage) {
  if(currentPage) { currentPage.teardown(); }
  currentPage = newPage;
  body.innerHTML = '';
  currentPage.render(body);
};

window.onload = function() {
  body = document.querySelector('body');
  Router
  .add('home', function() {
    var p = new Home();
    showPage(p);
  })
  .add(function() {
    Router.navigate('home');
  })
  .listen()
  .check();
}

Define Controller

  • path: frontend/js/controllers/Home.js
  • ?: onrender, onconstruct, onteardown, onupdate http://docs.ractivejs.org/latest/options
  • config gulp for automation ractive convert /frontend/tpl/.html -> .js (ractive & browserify)

Define View

  • Ractive component
  • MVC actually are just a definition & need to follow some rules with it
  • In this example, in the view template footer (make some data call from model like models/Version.js)

Define Model

  • Path: /frontend/js/models
  • Models share the same methods
  • Specify the URL -> Base module take care of the rest

MONGODB (MANAGING USER)

brew install mongodb
npm install mongodb --save

Update Model class

  • add update & delete method in models/Base.js

Update Page navigation & Routing

  • add tpl/navigation.html
  • {{#if}} expression & isLogged variable. (show or not show button when user login or logout)
  • on-click attribuite (interpreted by Ractive.js)
  • update Frontend/app.js navigation goto

Update Frontend & Register new user

  • add Register tempalte /tpl/register.html
  • update model/Base.js add setter metthod (?)
  • add model models/user.js
  • load UserModel on app.js (window.onload)

Update Backend API

npm install sha1 --save

User authentication with sessions

npm install cookie-session --save
  • Update frontend user login (app.js, template)
  • Note
delete user._id; // remove when return
delete user.password; // remote when return
req.session.user = user; // store to session

User profile

EXPRESS BASIC FORM

npm install express --save // express framework
npm install path --save // exact copy of the NodeJS ’path’ module published to the NPM registry.
npm install body-parser --save // Nodejs body parsing middleware -> take the body & parse to whatever you want

Sending Respond

  • path: /sample/express/hello.js

Static Web Server

  • path: /sample/express/express-static

Requests Basic Form (send, download...)

  • path: /sample/express/express-basic-form

EXPRESS BLOG SYSTEM

MongoDB & Middleware

npm install express --save
npm install path --save
npm install serve-favicon --save
npm install morgan --save // request logger middleware
npm install cookie-parser --save // parse cookie to object
npm install body-parser --save
npm install express-session --save // simple session middleware for express
npm install express-validator --save // Express middleware for the validator module. https://github.com/ctavan/express-validator
npm install connect-flash --save // Flash message middleware for Connect.
npm install mongoose --save // Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.

npm install debug --save
npm install jade --save
npm install server-favicon --save
npm install moment --save

Node Syntax
Handler
app.get
app.use: app.use() takes only one callback whereas app.all() can take multiple callbacks.
app.set
app.all

Middleware: callback of request Handler

Example
app.use( "/product" , mymiddleware);
// will match /product
// will match /product/cool
// will match /product/foo

app.all( "/product" , handler);
// will match /product
// won't match /product/cool   <-- important
// won't match /product/foo    <-- important

app.all( "/product/*" , handler);
// won't match /product        <-- Important
// will match /product/cool
// will match /product/foo
  • handler & middleware examples. Path: sample/handler/
  • Config mongodb
 mongod --directoryperdb --dbpath /Users/hungle/Sites/projects/mongodb/data/db --logpath /Users/hungle/Sites/projects/mongodb/log/mongo.log --logappend --rest // --install win

Router & View (Basic, Concept)

Categories (Basic, Concept)

Articles (Basic, Structure)

Comments

REFERENCE

API

npm install winston --save

ENVIRONMENT SETUP

sudo npm install -g n // node module
sudo n 4.4.7 //install node ver 4.4.7 
sudo npm install -g pm2 // install pm2
Run docker
./docker.sh 

TDD