1

实现监视代码修改和自动重启:supervisor

如果你有 PHP 开发经验,会习惯在修改 PHP 脚本后直接刷新浏览器以观察结果,而你在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止Node.js 再重新运行才会奏效。这是因为Node.js 只有在第一次引用到某部份时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,而 PHP 则总是重新读取并解析脚本(如果没有专门的优化配置)。Node.js的这种设计虽然有利于提高性能,却不利于开发调试,因为我们在开发过程中总是希望修改后立即看到效果,而不是每次都要终止进程并重启。supervisor 可以帮助你实现这个功能,它会监视你对代码的改动,并自动重启 Node.js。

使用方法很简单,首先使用 npm 安装 supervisor:

$ npm install -g supervisor

如果你使用的是 Linux 或 Mac,直接键入上面的命令很可能会有权限错误。原因是 npm需要把 supervisor 安装到系统目录,需要管理员授权,可以使用 sudo npm install -g supervisor 命令来安装。

接下来,使用 supervisor 命令启动 app.js( 可以视情况更改,比如当前需要启动:supervisor ./bin/www):

$ supervisor app.js

DEBUG: Running node-supervisor with
DEBUG: program 'app.js'
DEBUG: --watch '.'
DEBUG: --extensions 'node|js'
DEBUG: --exec 'node'
DEBUG: Starting child process with 'node app.js'
DEBUG: Watching directory '/home/byvoid/.' for changes.
HTTP server is listening at port 3000.

当代码被改动时,运行的脚本会被终止,然后重新启动。在终端中显示的结果如下:

DEBUG: crashing child
DEBUG: Starting child process with 'node app.js'
HTTP server is listening at port 3000.

supervisor 这个小工具可以解决开发中的调试问题。


Express安装后无法在命令行中调用

全局安装express的时候( npm install -g express),使用express命令失效,有如下两种原因。

  • 原因1:

安装的express是4.0以上的版本,express在4.0之后,需要安装the executable(执行器express-generator)才能执行express命令,

解决方案:

安装express-generator即可

npm install express-generator -g;

  • 原因2:

1)如果是用sudo apt-get install nodejs命令安装的nodejs,ubuntu在安装的时候为了避免包的冲突,将nodejs的命令操作改成nodejs,而不是node。
2)由于express安装时默认的nodejs命令是node,所以安装完后express命令会不起作用,本人的理解是express命令是在node名字的基础上继续其他操作的:
eg. 它可能是这样的 node xxx, 然后在其它命令xxx 于是就组合成了express这一系列的操作,既然node命令都没有用了 那么express自然也就失去了原来的效果

解决方案:
1)若express的版本为4.0以上
去 /usr/local/lib/node_modules/express-generator/bin 目录,改express文件的第一行 ,如下:

#!/usr/bin/env nodejs

2)若express的版本为4.0以下
去 /usr/local/lib/node_modules/express/bin 目录,改express文件的第一行 ,如下:

#!/usr/bin/env nodejs


路由响应的控制权转移

Express 支持同一路径绑定多个路由响应函数,例如:

app.all('/user/:username', function(req, res) {
    res.send('all methods captured');
});
app.get('/user/:username', function(req, res) {
    res.send('user: ' + req.params.username);
});

但当你访问任何被这两条同样的规则匹配到的路径时,会发现请求总是被前一条路由规则捕获,后面的规则会被忽略。原因是 Express 在处理路由规则时,会优先匹配先定义的路由规则,因此后面相同的规则被屏蔽。

Express 提供了路由控制权转移的方法,即回调函数的第三个参数 next ,通过调用next() ,会将路由控制权转移给后面的规则,例如:

app.all('/user/:username', function(req, res, next) {
    console.log('all methods captured');
    next();
});
app.get('/user/:username', function(req, res) {
    res.send('user: ' + req.params.username);
});

当访问被匹配到的路径时,如 http://localhost:3000/user/carbo,会发现终端中打印了 all methods captured ,而且浏览器中显示了 user: carbo 。这说明请求先被第一条路由规则捕获,完成 console.log 使用 next() 转移控制权,又被第二条规则捕获,向浏览器返回了信息。


ejs 的标签系统

<% code %> :JavaScript 代码。
<%= code %> :显示替换过 HTML 特殊字符的内容。(在routes的js文件中返回的内容)
<%- code %> :显示原始 HTML 内容。
<%# code %> :注释标签,不执行,也没有输出。
<%%%>: 输出字面的 '<%%>'
-%> :Trim-mode ('newline slurp') 标签, 移除随后的换行符


Bug:Can't set headers after they are sent.(控制台) ReferenceError: body is not defined at eval(页面)

基本上的意思好像是说已经把headers传递给页面了,所以不能再次设置它们。

出现的原因:
在layout.ejs中,使用<%- body %>,表示这部分内容是各个模板文件独有的。
在admin.ejs中,又一次使用<%- body %>,就会报错

解决方式:
在admin.ejs中,删掉<%- body %>。

也就是说,admin.ejs作为/uses路由的默认模板,它实际上还是要通过layout.ejs来进行统一渲染的。因为模板文件不是孤立展示的,默认情况下所有的模板都继承自 layout.ejs


REST 设计模式常用的请求方法

GET:获取
POST:新增
PUT:更新
DELETE:删除
HEAD:请求指定资源的响应头
TRACE:回显服务器收到的请求,主要用于测试或诊断
CONNECT:HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS:返回服务器支持的HTTP请求方法。


盛夏光年
98 声望5 粉丝