NodeJS的流行也带来了开发由前端转到全栈,前端不再局限于页面如何展现,用户如何操作,也设计到整个应用的架构以及业务流程。
本篇来简单的通过实例,讲述node中web开发的模式。
参考来自《Node web开发》一书。
关于node
node是基于事件的异步驱动系统,通过可扩展的方式创建网络服务器。
例如,创建一个网络服务器:
var http_port = 8124; var http = require('http'); var server = http.createServer(function (req,res){ ....自己的代码 }); server.listen(http_port);
这样就可以创建一个简单的服务器。
关于npm
npm是node的包管理工具,node里面有很多的模块,可以通过require('模块名字')的方式加载到项目中。
常用的命令:
npm init 创建项目的package.json文件,配置其信息以及依赖项
npm install 通过package.json的声明,安装需要的包
npm install xxxx 安装xxxx包
npm install xxxx --save-dev 以开发模式安装xxxx包,当用于生产环境时,不会下载开发模式的xxxx
关于项目布局
在node中,很注重模块化,按照commonjs的思想,尽量把功能分散到模块中进行重用。
但是也有点弊端,会出现很多松散的文件,不易于管理。
通常node中都会把第三方的模块包,放在node_modules文件夹中,node也会在require()的时候,自动向上搜索该文件家,引用其js。
node_modules中的js文件,大多是一些加载自动执行的文件,或者对外暴露出一定的接口,比如:
(function(a,b){}( this, function(){ //..... }));
或者
var xxx = require('xxx'); exports.funca = function(){ //.......xxx } exports.funcb = function(){ //.....xxx }
关于代码
本篇的项目做了一个小网站,通过模块化开发,项目组织如下:
app: |——app-node.js 定义web服务器 |——home-node.js 定义home主页模块 |——htutil.js 定义工具模块,用于定义导航,以及网页模板替换方法,和获取http信息 |——mult-node.js 通过get方法获取参数信息,并执行加法 |——package.json 定义网站项目信息
app-node.js代码:
var http_port = 8124; var http = require('http'); var htutil = require('./htutil'); var server = http.createServer(function (req,res){ console.log("in server!"); htutil.loadParams(req,res,undefined); if(req.requrl.pathname === '/'){ require('./home-node').get(req,res); }else if(req.requrl.pathname === '/square'){ require('./square-node').get(req,res); }else if(req.requrl.pathname === '/factorial'){ require('./factorial-node').get(req,res); }else if(req.requrl.pathname === '/fibonacci'){ require('./fibonacci-node').get(req,res); }else if(req.requrl.pathname === '/mult'){ require('./mult-node').get(req,res); }else{ res.writeHead(404,{'Content-Type':'text/plain'}); res.end("bad url"+req.url); } }); server.listen(http_port); console.log('listening to http://localhost:8124');
home-node.js
var htutil = require('./htutil'); exports.get = function(req,res){ res.writeHead(200,{ 'Content-Type':'text/html' }); res.end(htutil.page("Math Wizard", htutil.navbar(), "<p>Math Wizard</p>" )); }
mult-node.js
var htutil = require("./htutil"); exports.get = function(req,res){ res.writeHead(200,{ 'Content-Type':'text/html' }); var result = req.a * req.b; res.end( htutil.page("Multiplication",htutil.navbar(),[ (!isNaN(req.a) && !isNaN(req.b) ?( "<p class='result'>{a}*{b}={result}</p>" .replace("{a}",req.a) .replace("{b}",req.b) .replace("{result}",req.a*req.b) ) :""), "<p>Enter numbers to multiply</p>", "<form name='mult' action='/mult' method='get'>", "A:<input type='text' name='a' /><br/>", "B:<input type='text' name='b' /><br/>", "<input type='submit' value='Submit' /></form>" ].join('\n')) ); }
htutil.js
var url = require('url'); //get url params a & b exports.loadParams = function(req,res,next){ req.requrl = url.parse(req.url,true); req.a = (req.requrl.query.a && !isNaN(req.requrl.query.a)) ?new Number(req.requrl.query.a) :NaN; req.b = (req.requrl.query.b && !isNaN(req.requrl.query.b)) ?new Number(req.requrl.query.b) :NaN; if(next) next(); } // exports.navbar = function(){ return ["<div class='navbar'>", "<p><a href='/'>home</a></p>", "<p><a href='/mult'>Multiplication</a></p>", "<p><a href='/square'>Square's</a></p>", "<p><a href='/factorial'>factorial's</a></p>", "<p><a href='/fibonacci'>Fibonacci's</a></p>", "</div>" ].join('\n'); } // exports.page = function(title,navbar,content){ return ["<html><head><title>{title}</title></head><body>", "<td>{navbar}</td><td>{content}</td>", "</tr></table></body></html>" ].join('\n') .replace("{title}",title,"g") .replace("{navbar}",navbar,"g") .replace("{content}",content,"g"); }
package.js
{ "name": "chap04", "version": "1.0.0", "description": "", "main": "app-node.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
执行命令行:
node app-node.js
访问http://localhost:8124,就可以访问到网址: