一、装备
我个人PC环境是Ubuntu14+JDK7,所以下面的步骤及问题也是基于此进行及产生的。
二、Nodejs及npm的安装
这个安装的过程在网上有很多教程,这里就不详细讲了。
$ sudo apt-get install python
$ sudo apt-get install build-essential
$ sudo apt-get install gcc
$ sudo apt-get install g++
$ sudo apt-get install nodejs
$ sudo apt-get install npm
查看Nodejs的版本,网上很多教程都写的是:
node -v
但一直node命令找不到的异常,使用以下命令执行成功:
nodejs -v
终端显示:
v0.10.25
查看npm版本是
npm -v
1.3.10
三、使用npm来安装supervisor工具及express框架
1、supervisor
在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止 Node.js 再重新运行才会奏效。这是因为 Node.js 只有在第一次引用到某部份时才会去解析脚 本文件,以后都会直接访问内存,避免重复载入。Node.js的这种设计虽然有利于提高性能,却不利于开发调试,因 为我们在开发过程中总是希望修改后立即看到效果,而不是每次都要终止进程并重启。
supervisor 可以帮助你实现这个功能,它会监视你对代码的改动,并自动重启 Node.js。
a) 全局安装 (我的选择)
npm install supervisor -gd
b) 安装在当前文件夹下
npm install supervisor
安装成功后,命令行会提示 npm info ok
-g代表安装到NODE_PATH的lib里面,而-d代表把相依性套件也一起安装。如果沒有-g的话会安装目前所在的目录(会建立一个node_modules的文件夹)。
通过以下命令了查看supervisor的帮助文档,
supervisor -hellp
终端显示:
/usr/bin/env: node: 没有那个文件或目录
经查找后,发现npm在安装模块的时候,会把源码及执行文件分开。
/usr/local/lib/node_modules 源码目录
/usr/local/bin 执行文件目录
注意:这里也是和网上的大部分教程不一样的地方,网上的教程都说源码及执行文件都是放在/usr/local/lib/node_modules 目录下的,估计是npm版本不同的原因。
找到并查看supervisor的执行文件:
#!/usr/bin/env node
var path = require("path")
, fs = require("fs")
, args = process.argv.slice(1)
var arg, base;
do arg = args.shift();
while ( fs.realpathSync(arg) !== __filename
&& (base = path.basename(arg)) !== "node-supervisor"
&& base !== "supervisor"
&& base !== "supervisor.js"
)
require("./supervisor").run(args)
看到supervisor的介绍,我们很容易得知,这个小模块的主要功能有两个:
1、关闭正在执行的项目
2、启动前面关闭的项目
这里报的错误是没有找到node,而且很清楚地发现执行文件的第一行使用的命令是!/usr/bin/env node ,回想前面查看Nodejs版本的命令。项目启动用到的应该是Nodejs本身的命令nodejs,
于是将这一行修改如下进行尝试,问题得到解决。
#!/usr/bin/env nodejs
终端显示supervisor的帮助如下:
Node Supervisor is used to restart programs when they crash.
It can also be used to restart programs when a *.js file changes.
Usage:
supervisor [options] <program>
supervisor [options] -- <program> [args ...]
Required:
<program>
The program to run.
Options:
-w|--watch <watchItems>
A comma-delimited list of folders or js files to watch for changes.
When a change to a js file occurs, reload the program
Default is '.'
-i|--ignore <ignoreItems>
A comma-delimited list of folders to ignore for changes.
No default
-p|--poll-interval <milliseconds>
How often to poll watched files for changes.
Defaults to Node default.
-e|--extensions <extensions>
Specific file extensions to watch in addition to defaults.
Used when --watch option includes folders
Default is 'node,js'
-x|--exec <executable>
The executable that runs the specified program.
Default is 'node'
--debug
Start node with --debug flag.
--debug-brk[=port]
Start node with --debug-brk[=port] flag.
--harmony
Start node with --harmony flag.
-n|--no-restart-on error|exit
Don't automatically restart the supervised program if it ends.
Supervisor will wait for a change in the source files.
If "error", an exit code of 0 will still restart.
If "exit", no restart regardless of exit code.
--force-watch
Use fs.watch instead of fs.watchFile.
This may be useful if you see a high cpu load on a windows machine.
-h|--help|-?
Display these usage instructions.
-q|--quiet
Suppress DEBUG messages
-V|--verbose
Show extra DEBUG messages
Examples:
supervisor myapp.js
supervisor myapp.coffee
supervisor -w scripts -e myext -x myrunner myapp
supervisor -- server.js -h host -p port
注意:根据帮助文档,查看supervisor的命令是supervisor -V 。命令中的V是大写,安装过程中我发现windows下小写也行,但在我的ubuntu14的环境下必须是大写。
2、express
a) 全局安装 (我的选择)
npm install express -gd
b) 安装在当前文件夹下
npm install express
在安装完后,express与supervisor一样,也存在Nodejs命令不符合的问题,同样的方式找到执行文件进行修改此命令即可。
安装完了express,如果版本是4.0及以上的话,还要安装另外一个模块,express才能使用。
sudo npm install -g express-generator
四、项目的建立及执行
1、新建一个名称为test的项目
2、使用express框架
cd 到test目录的上级目录,执行以下命令
express -e test
执行完后,回到项目目录查看:
node_modules, 存放所有的项目依赖库。
package.json,项目依赖配置及开发者信息
app.js,程序启动文件
public,静态文件(css,js,img)
routes,路由文件(MVC中的C,controller)
views,页面文件(Ejs模板)
bin ,存放默认启动的脚本
package.json :
{
"name": "pcrm",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"express": "~4.2.0",
"static-favicon": "~1.0.0",
"morgan": "~1.0.0",
"cookie-parser": "~1.0.1",
"body-parser": "~1.0.0",
"debug": "~0.7.4",
"ejs": "~0.8.5"
}
}
app.js:
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
/// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
bin/www:
#!/usr/bin/env node
var debug = require('debug')('pcrm');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
3、执行
cd到test目录下
执行方法1:
npm start
终端显示异常:
> test@0.0.1 start /home/benben/workspace/test
> node ./bin/www
sh: 1: node: not found
npm ERR! weird error 127
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read
/usr/share/doc/nodejs/README.Debian
npm ERR! not ok code 0
还是node命令的问题,修改package.json 文件中的
"start": "node ./bin/www" 为 "start": "nodejs ./bin/www"
bin/www文件中的
#!/usr/bin/env node 为 #!/usr/bin/env nodejs
执行成功
npm是什么东西呢?大部分的Java程序员都使用过Maven。而npm的职能与Maven相似,是Nodejs的包管理工具,可以使用它来下载包、查看文件等功能用express创建的应用程序是一个符合CommonJS规范的一个nodejs包npm执行的时候会读取当前目录的package.json文件,这个也就是我上面那个bug出现的原因执行npm start其实是执行package.json中的script对应的对象中的start属性所对应的命令。
所以其实如果吧package.json中的start改成test或者其他字符串,然后你在终端敲上npm test/或者其他,程序照样会运行 。
其实package.json就是一个配置文件,只是我们之前用的xml格式,但是在nodejs用的是json可以,简单容易理解。从package.json我们可以看出来npm start其实执行的是./bin/www里面是创建一个服务器然后监听3000端口,所以我们可以在浏览器中通过输入"localhost:3000"来访问应用程序。
执行方法2:
npm start 是启用的 /bin/www文件里的脚本
如果你想用nodejs 启动服务 可以在app.js中添加如下代码
app.listen(3000);
注意:上面的语句得加在module.exports = app;之前。
nodejs app.js
得到同样的结果。
执行方法3:
使用supervisor进行热部署的执行方便调试
supervisor app.js
终端显示异常:
Running node-supervisor with
program 'app.js'
--watch '.'
--extensions 'node,js'
--exec 'node'
Starting child process with 'node app.js'
execvp(): No such file or directory
Watching directory '/home/benben/workspace/pcrm' for changes.
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:988:11)
at Process.ChildProcess._handle.onexit (child_process.js:779:34)
这里解决的过程就不详细说了,重点是--exec 'node'这个,会发现supervisor执行的还是node命令,而不是nodejs。修改supervisor源文件目录下的supervisor.js文件
if (!executor) {
executor = (programExt === "coffee" || programExt === "litcoffee") ? "coffee" : "node";
}
为
if (!executor) {
executor = (programExt === "coffee" || programExt === "litcoffee") ? "coffee" : "nodejs";
}
再次执行成功,项目修改后,Nodejs也会自动重启。
五、IDE的选择