Node.js 简介
& 快速开发 Web 产品

Who am I?我是谁?

Alibaba Data EDP

阿里巴巴数据平台EDP,花名@苏千

Chinese nodejs community: cnodejs.org


npm: cnpmjs.org/~fengmk2

Github: @fengmk2

Blog: http://fengmk2.github.com

Twitter: @fengmk2

Weibo: @Python发烧友 , @FaWave

内容简介

* 简单介绍 Node.js 的历史以及现状

* 以一个实用的Web小应用介绍基于 Node.js 的Web开发过程

Node.js 简介

什么是 Node.js

1

Node.js

* 09年发布, 最新稳定版本 v0.10.26

* github stars 排名第三

1

Node.js 最常被提起的特性

* 基于 google v8 引擎 (快速)

* 事件驱动 (不同的编程思维)

* ⾮阻塞I/O (⾼高效)

* 单线程 (模型简单, ⽆锁)

事件循环

1

NPM: Node Packaged Modules

* 超过 64000+ 个模块

* 跟随 Node.js 源码分发的包管理⼯工具

* 精简的 Node.js 内核的丰富扩展

1

NPM 模块数量增长惊人

1

谁在使用 Node.js?

Learn More About The Node Community

1

Node.js 到底能干吗?

服务器端

* Web 服务

* restful API 服务

* 前后端彻底分离的web前端服务

* 全栈 web 应⽤

* ⾼性能中间层

* ⾼实时性应⽤用(游戏服务器/在线聊天室)

服务器端

1

前端工具

1

更多领域

1

Node.js 简介小结

* Node.js 还在飞速发展中

* Node.js 不仅仅能做服务端开发, 还能做你没想象到的

* 等待你开启人生的第一个 node 进程

什么是 Web 开发

Web开发

Why Nodejs?

IO密集型

* 磁盘IO:读写文件

* 网络IO:数据库,Cache,Services

* 进程:进程通信,进程调用

V8有多快?

fibonacci

高楼平地起: Hello World

helloworld.js

var http = require('http');
http.createServer(function (req, res) {
  console.log('%s %s : %j', req.method, req.url, req.headers);
  req.on('end', function () {
    res.writeHeader(200, { 'Content-Type': 'text/html' });
    res.end('Hello QCon Hangzhou');
  });
}).listen(1984);

Event driven: req.on('end', function () {})

看看得到什么

hello world result

console.log()

$ node helloworld.js

GET / : {"host":"localhost.cnodejs.org:1984","connection":"keep-alive","cache-control":"max-age=0","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","accept-encoding":"gzip,deflate,sdch","accept-language":"zh-CN,zh;q=0.8,en;q=0.6,en-US;q=0.4","accept-charset":"GBK,utf-8;q=0.7,*;q=0.3"}

GET /favicon.ico : {"host":"localhost.cnodejs.org:1984","connection":"keep-alive","accept":"*/*","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4","accept-encoding":"gzip,deflate,sdch","accept-language":"zh-CN,zh;q=0.8,en;q=0.6,en-US;q=0.4","accept-charset":"GBK,utf-8;q=0.7,*;q=0.3"}

说笑吧,太简单了吧

Simple todo

使用 leveldb 存储,快速实现最简单的两个功能:

* 添加任务

* 显示任务

* 完成任务

目录结构

$ tree -I node_modules
.
├── Makefile
├── README.md
├── app.js
├── common
│   └── db.js
├── config.js
├── controllers
│   ├── home.js
│   └── task.js
├── package.json
├── proxy
│   └── task.js
├── public
│   ├── images
│   │   ├── doing.gif
│   │   └── finished.jpg
│   └── styles
│       ├── index
│       │   ├── images
│       │   │   ├── bg_1.png
│       │   │   ├── email.png
│       │   │   ├── home.png
│       │   │   ├── msn.png
│       │   │   ├── ok.gif
│       │   │   ├── qq.png
│       │   │   └── website.png
│       │   └── style.css
│       └── reset.css
├── routes.js
└── views
    ├── error.html
    ├── index.html
    ├── layout.html
    └── task
        └── edit.html

package.json

使用 npm init 生成项目的 package.json

$ npm init

使用强大的第三方模块加速开发效率

依赖模块:

  "dependencies": {
    "utility": "0.1.11",
    "connect": "2.6.0", // web server, static files hosting
    "urlrouter": "0.2.3", // url routing
    "connect-render": "0.1.7", // ejs template engine helper
    "level": "0.18.0" // leveldb client
  }

主页面效果

HTML + CSS,服务器端使用 ejs 模板引擎渲染

index page

主页面 URL Routing

URL路由简单明了

var home = require('./controllers/home');
// HTTP GET / => home controller
app.get('/', home);

Home Controller

module.exports = function home(req, res, next) {
  res.render('index.html', {
    tasks: [] // 稍后会增加数据库逻辑
  });
};

index.html 模板

<div class="box todos">
  <h2 class="box">待办事项</h2>
  <ul>
    <% for (var i = 0; i < tasks.length; i++) {
      var task = tasks[i];
      var classname = task.finished ? 'class="finished"' : '';
    %>
      <li <%- classname %>>
        <% if (!task.finished) { %>
          <%= task.title %>
          &nbsp;
          <a href="/task/<%- task.id %>/finish">完成</a>
        <% } else { %>
          <del><%= task.title %></del>
          &nbsp;
          <a href="/task/<%- task.id %>/unfinish">恢复</a>
        <% } %>
      </li>
    <% } %>
  </ul>
</div>

静态文件服务

直接使用 connect 的 static 中间件模块

app.use('/public',
  connect.static(path.join(__dirname, 'public')));

CSS,图片,客户端脚本

<link href="/public/styles/reset.css" rel="stylesheet" type="text/css" />
<link href="/public/styles/index/style.css" rel="stylesheet" type="text/css" />

添加任务

URL路由配置

var task = require('./controllers/task');

app.post('/task', task.add);

HTML模板及CSRF保护

  <div class="box post">
    <h2>新增</h2>
    <form action="/task" method="post" id="post_new">
      <input type="hidden" name="_csrf" value="<%- _csrf %>" />
      <p><input type="text" name="title" class="long_txt" /></p>
      <p><input type="submit" class="submit" value="添加" /></p>
    </form>
  </div>

添加任务 controller 实现代码

var Task = require('../proxy/task');

exports.add = function (req, res, next) {
  var title = req.body.title;
  var task = { title: title, finished: 0, created_at: new Date() };
  Task.insert(task, function (err, item) {
    if (err) {
      return next(err);
    }
    res.writeHeader(302, {
      Location: '/'
    });
    res.end();
  });
};

在主页面上显示刚才添加的任务

var Task = require('../proxy/task');

module.exports = function home(req, res, next) {
  Task.list(function (err, tasks) {
    if (err) {
      return next(err);
    }
    res.render('index.html', {
      tasks: tasks
    });
  });
};

添加任务效果

add task

完成任务

URL Routing

// GET /task/50843cf924438a2dfa000001/finish
app.get('/task/(:id)/finish', task.finish);

controller 实现代码

exports.finish = function (req, res, next) {
  var tid = req.params.id; // mapping from url
  var task = { finished: 1, updated_at: new Date() };
  Task.updateById(tid, task, function (err, item) {
    if (err) {
      return next(err);
    }
    res.writeHeader(302, {
      Location: '/'
    });
    res.end();
  });
};

整体效果

todo2

Talk is cheap

删除任务,编辑任务,用户系统...,剩余的功能,等你来完成。

“自己动手,丰衣足食”

fork github.com/fengmk2/nodejs-web-dev, then do it.

应用展示

淘宝指数

shu

数据魔方

mofang

内部 NPM Web

npmweb

CNodejs 社区

cnode

cnpmjs.org

cnpmjs.org

推荐资源

* The Node Beginner Book, 中文版: Node入门

* @朴灵 深入浅出Node.js

* 七天学会NodeJS

* StrongLoop blog 绝对是 Node.js 最新知识的权威博客

http://fengmk2.github.com/ppt/nodejs-web-dev.html

web.emit('Thanks')
&&
console.log('end');

/

#