nodejs开发指南 学习
###CommonJS模块化相关的目录规范
- package.json 必须在包的顶层目录下;
- 二进制文件应该在 bin 目录下;
- JavaScript 代码应该在 lib 目录下;
- 文档应该在 doc 目录下;
- 单元测试应该在 test 目录下;
###应用部署需要注意的地方
- 故障恢复机制
- 日志
- 。。。
###建立一个web站点
安装express模块,通过命令express init
###文件相关操作
功能 | 异步函数 | 同步函数 |
---|---|---|
打开文件 | fs.open(path,flags, [mode], [callback(err, fd)]) | fs.openSync(path, flags, [mode]) |
关闭文件 | fs.close(fd, [callback(err)]) | fs.closeSync(fd) |
读取文件(文件描述符) | fs.read(fd,buffer,offset,length,position,[callback(err, bytesRead, buffer)]) | fs.readSync(fd, buffer, offset, length, position) |
写入文件(文件描述符) | fs.write(fd, buffer, offset, length, postion, [callback(err, bytesWritten, buffer)]) | fs.writeSync(fd, buffer, offset, length, position) |
读取文件内容 | fs.readFile(filename, [encoding],[callback(err, data)]) | fs.readFileSync(filename, [encodeing]) |
写入文件内容 | fs.writeFile(filename, data, [encoding], [callback(err)]) | |
删除文件 | fs.unlink(path, [callback(err)]) | fs.unlinkSync(path) |
创建目录 | fs.mkdir(path, [mode], [callback(err)]) | fs.mkdirSync(path, [mode]) |
删除目录 | fs.rmdir(path, [callback(err)]) | fs.readdirSync(path) |
读取目录 | fs.readdir(path, [callback(err, files)]) | fs.readdirSync(path) |
获取真实路径 | fs.realpath(path, [callback(err, resolvedPath)]) | fs.realpathSync(path) |
更名 | fs.rename(path1, path2, [callback(err)]) | fs.renameSync(path1, path2) |
截断 | fs.truncate(fd, len, [callback(err)]) | fs.truncateSync(fd, len) |
更改所有权 | fs.chown(path, uid, gid, [callback(err)]) | fs.chownSync(path, uid, gid) |
更改所有权(文件描述符) | fs.fchown(fd, uid, gid, [callback(err)]) | fs.fchownSync(fd, uid, gid) |
更改所有权(不解析符号链接) | fs.lchown(path, uid, gid, [callback(err)]) | fs.lchownSync(path, uid, gid) |
更改权限 | fs.chmod(path, mode, [callback(err)]) | fs.chmodSync(path, mode) |
更改权限(文件描述符) | fs.fchmod(fd, mode, [callback(err)]) | fs.fchmodSync(fd, mode) |
更改权限(不解析符号链接) | fs.lchmod(path, mode, [callback(err)]) | fs.lchmodSync(path, mode) |
获取文件信息 | fs.stat(path, [callback(err, stats)]) | fs.statSync(path) |
获取文件信息(文件描述符) | fs.fstat(fd, [callback(err, stats)]) | fs.fstatSync(fd) |
获取文件信息(不解析符号链接) | fs.lstat(path, [callback(err, stats)]) | fs.lstatSync(path) |
创建硬链接 | fs.link(srcpath, dstpath, [callback(err)]) | fs.linkSync(srcpath, dstpath) |
创建符号链接 | fs.symlink(linkdata, path, [type], [callback(err)]) | fs.symlinkSync(linkdata, path, [type]) |
读取链接 | fs.readlink(path, [callback(err, linkString)]) | fs.readlinkSync(path) |
修改文件时间戳 | fs.utimes(path, atime, mtime, [callback (err)]) | |
fs.utimesSync(path, atime, mtime) | ||
修改文件时间戳(文件描述符) | fs.futimes(fd, atime, mtime, [callback(err)]) | fs.futimesSync(fd, atime, mtime) |
同步磁盘缓存 | fs.fsync(fd, [callback(err)]) | fs.fsyncSync(fd) |
###http Router相关数据读取以及flash locals使用技巧
-
获取request参数
1、例如:127.0.0.1:3000/index,这种情况下,我们为了得到index,我们可以通过使用req.params得到,通过这种方法我们就可以很好的处理Node中的路由处理问题,同时利用这点可以非常方便的实现MVC模式; 2、例如:127.0.0.1:3000/index?id=12,这种情况下,这种方式是获取客户端get方式传递过来的值,通过使用req.query.id就可以获得,类似于PHP的get方法; 3、例如:127.0.0.1:300/index,然后post了一个id=2的值,这种方式是获取客户端post过来的数据,可以通过req.body.id获取,类似于PHP的post方法;
-
flash与locals使用
express3.0以后就不支持flash了,需要我们手动安装中间件,如下:
npm install connect-flash
这样就可以使用req.flash了。
res.locals是一个临时存对象的属性。
###模块建立与export使用
一个模块就是一个js文件,这个js文件中使用export模块公开接口对外公开了一下方法或属性,可以通过require方法调用到对外公开的方法或属性。
var name;
exports.setName = function(thyName) {
name = thyName;
};
exports.sayHello = function() {
console.log('Hello ' + name);
};
上面对外公开了setName和sayHello函数。
###调试工具
使用node-inspector工具调试Node.js
npm install -g node-inspector
然后在运行时使用以下命令运行:
node-debug app.js
将会自动弹出调试工具。
ejs是我这种对html只了解一些皮毛的人比较适合。
安装:
npm install ejs
三个语法:
- <% code %>
- <%= code %>
- <%- code %>
嵌套模板
inculde 指令
<ul>
<% users.forEach(function(user){ %>
<% include user/show %>
<% }) %>
</ul>
user/show 是用户的一个html模板
如果你不想使用<%作为语法开始,%>作为语法结束,可以自定义:
var ejs = require('ejs');
ejs.open = '{{';
ejs.close = '}}';
这样开始的语法就变成了 {{ code }}、{{= code }}、{{- code }}
###日志功能
在新版本的express中已经把日志功能去掉了,需要用中间件的方式来实现日志功能。
// 日志功能添加
var fs = require('fs');
var accessLogfile = fs.createWriteStream('access.log',{flags : 'a'});
var errorLogfile = fs.createWriteStream('error.log', {flags : 'a'});
// 访问日志
app.use(function(req, res, next) {
var error = res.locals.error;
if (error) {
var meta = '[' + new Date() + '] ' + req.url + ' ' + err.message + '\n';
errorLogfile.write(meta + err.stack + '\n');
}
else {
var message = req.url
var meta = '[' + new Date() + '] ' + req.url + ' ' + util.inspect(req.body) + ' ' + util.inspect(req.params);
accessLogfile.write(meta + '\n');
}
next();
});
// 错误日志
app.use(function(err, req, res, next) {
var meta = '[' + new Date() + '] ' + req.url + ' ' + err.message + '\n';
errorLogfile.write(meta + err.stack + '\n');
next();
});
###多核使用
从0.6版本开始,Node.js提供了一个核心模块:cluster。cluster的功能是生成与当前进程相同的子进程,并允许父进程和子进程之间共享端口。
类似的核心模块:child_process,单cluster允许跨进程端口复用。
var cluster = require('cluster');
-
判断是否为主进程
if (cluster.isMaster)
-
开启一个新子进程
var worker = cluster.fork();
-
结束一个进程
process.kill(worker.pid);
###宕机自动重启
-
监听一个工作进程结束,并重启
cluster.on('death', function (worker) { // 当一个工作进程结束时,重启工作进程 delete workers[worker.pid]; worker = cluster.fork(); workers[worker.pid] = worker; });
-
监听程序主进程结束,结束所有工作进程
process.on('SIGTERM', function () { for (var pid in workers) {  process.kill(pid); } process.exit(0); });
###同一机器部署多套
Nginx使用