|
安装 Nodejs
去Nodejs官网根据自己的操作系统下载对应的安装包并安装。我们就有了NodeJS和npm环境。npm是Node的包管理工具,会在安装NodeJS时一并安装。可以用以下命令查看版本号验证我们的安装成功与否:
sunjingdeMacBook-Pro:microblog sunjing$ node -v
v0.12.2
sunjingdeMacBook-Pro:microblog sunjing$ npm -v
2.7.4
安装 express-generator
我们使用express作为开发框架,与1版不同,新版的express已经不可以使用:
express -t ejs microblog
来快速建立网站结构,而是要额外安装express-generator来生成网站框架。
npm install -g express-generator
'-g' 参数表示全局安装,这样我们就可以直接在命令行上使用了。
创建项目
创建框架
在要存放项目的目录打开终端或命令行,使用以下命令建立网站框架:
express -e microblog
'-e' 参数表示使用ejs作为模板引擎,如不加会默认使用jade。
执行命令后会看到如下结果:
sunjingdeMacBook-Pro:~ sunjing$ express -e microblog
create : microblog
create : microblog/package.json
create : microblog/app.js
create : microblog/public
create : microblog/public/javascripts
create : microblog/public/images
create : microblog/public/stylesheets
create : microblog/public/stylesheets/style.css
create : microblog/routes
create : microblog/routes/index.js
create : microblog/routes/users.js
create : microblog/views
create : microblog/views/index.ejs
create : microblog/views/error.ejs
create : microblog/bin
create : microblog/bin/www
install dependencies:
$ cd microblog && npm install
run the app:
$ DEBUG=microblog:* ./bin/www
编辑依赖项
打开项目目录,找到package.json文件,将其中的依赖项修改如下,在默认的依赖项里添加上我们后面将会用到的一些模块。
"dependencies": {
"body-parser": "~1.12.0",
"cookie-parser": "~1.3.4",
"debug": "~2.1.1",
"ejs": "~2.3.1",
"express": "~4.12.2",
"express-session":"*",
"morgan": "~1.5.1",
"serve-favicon": "~2.2.0",
"mongodb":"*",
"connect-mongo":"*",
"connect-flash":"*",
"log4js":"*"
}
关于依赖项版本号的书写规则可以查看Difference between tilde(~) and caret(^) in package.json,需要注意的是虽然前面我们已经全局安装了express-generator,这里我们仍然需要本地安装express模块。
安装依赖项
好啦,现在可以安装我们上面列出的依赖项了,在项目目录里运行如下命令,即会多出来一个node_modules目录,存放了各依赖模块。
sunjingdeMacBook-Pro:microblog sunjing$ npm install
运行项目
在新的express框架下,1版上用的
node app.js
启动命令已经不再适用,要改用
sunjingdeMacBook-Pro:microblog sunjing$ npm start
> microblog@0.0.0 start /Users/sunjing/microblog
> node ./bin/www
为什么呢?因为在package.json中有这样配置
"scripts": {
"start": "node ./bin/www"
}
所以用 npm start 命令等同于:
sunjingdeMacBook-Pro:microblog sunjing$ node ./bin/www
我们后面使用forever管理进程的时候还会提到这里。
这时候我们已经可以在浏览器里用3000端口http://localhost:3000/查看我们的网站页面了。
打开 app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-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');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
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;
app.js 其中
var routes = require('./routes/index');
var users = require('./routes/users');
表示引用routes文件夹下的index.js和users.js
app.use('/', routes);
app.use('/users', users);
// 挂载至 / 的中间件,任何指向 / 的请求都会执行它
// 挂载至 /users 的中间件,任何指向 /users 的请求都会执行它
这里还有应用级中间件、路由级中间件(区别待查。。。欢迎交流)
应用级中间件
应用级中间件绑定到 app 对象 使用 app.use() 和 app.METHOD(), 其中, METHOD 是需要处理的 HTTP 请求的方法,例如 GET, PUT, POST 等等,全部小写。例如:
var app = express();
// 没有挂载路径的中间件,应用的每个请求都会执行该中间件
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 挂载至 /user/:id 的中间件,任何指向 /user/:id 的请求都会执行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 路由和句柄函数(中间件系统),处理指向 /user/:id 的 GET 请求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
app.use 路由级中间件
路由级中间件和应用级中间件一样,只是它绑定的对象为 express.Router()。
var app = express();
var router = express.Router();
// 没有挂载路径的中间件,通过该路由的每个请求都会执行该中间件
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 一个中间件栈,显示任何指向 /user/:id 的 HTTP 请求的信息
router.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 一个中间件栈,处理指向 /user/:id 的 GET 请求
router.get('/user/:id', function (req, res, next) {
// 如果 user id 为 0, 跳到下一个路由
if (req.params.id == 0) next('route');
// 负责将控制权交给栈中下一个中间件
else next(); //
}, function (req, res, next) {
// 渲染常规页面
res.render('regular');
});
// 处理 /user/:id, 渲染一个特殊页面
router.get('/user/:id', function (req, res, next) {
console.log(req.params.id);
res.render('special');
});
// 将路由挂载至应用
app.use('/', router);
router.use |
|