Node.js入门(3)之Express项目架构分析

发表日期:  Creative Commons Licence

部分参考 http://blog.csdn.net/a1104258464/article/details/50976786

package.json

内含项目的信息和依赖模块。养成好习惯,阅读别人的项目先看package.json。

{
  "name": "second", 	//项目名(名字里不要包含“js”和“node”)
  "version": "0.0.0", 	//版本号
  "private": true, 		//是否私有(设置为true则不会发布到npm上)
  "scripts": { 			//项目的启动配置,需要在命令行输入npm run start之类的。
    "start": "node ./bin/www",
    "dev": "./node_modules/.bin/nodemon ./bin/www"
  },
  "dependencies": {		//外部依赖的包,别人的轮子,保存在node_modules下
    "body-parser": "~1.18.2",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "ejs": "~2.5.7",
    "express": "~4.15.5",
    "morgan": "~1.9.0",
    "serve-favicon": "~2.4.5"
  },
  "devDependencies": {	//开发调试时依赖的包
    "nodemon": "^1.12.1"
  }
}

bin

存放可执行文件的文件夹,如 start启动配置中的./bin/www,非必须。仅仅是一个约定俗成的文件夹命名和代码归类方式,一般放.js格式文件。

www.js

express-generator创建的文件,于/bin目录下,为默认的启动路径文件。

//模块依赖
var app = require('../app');
var debug = require('debug')('second:server');
var http = require('http');

//获得端口并保存。
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);	//为app的settings添加port这个设置。
//即 app.get('port'); => '3000'

//创建HTTP服务器
var server = http.createServer(app);

//在创建的端口进行监听
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

//将对象转换为int类型,为port服务
function normalizePort(val) {
  var port = parseInt(val, 10);
 //是否是数字
  if (isNaN(port))
    return val;

  if (port >= 0) 
    return port;

  return false;
}

//为HTTP服务器设置error事件监听器
function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  //返回一些特殊的错误提示
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

//为HTTP服务器设置listening事件监听器
function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

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');
//加载routes文件夹下的index.js路由文件和users文件,未特别指出一个文件夹下的路由文件则默认选择为./index文件。
var index = require('./routes/index');
var users = require('./routes/users');
//创建express实例
var app = express();

//设置一些settings变量,设置view为视图文件的位置,即ejs文件放在view文件夹 __dirname是全局变量,表示当前执行文件的路径
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');	//设置模版为ejs

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));		//加载logger(日志记录器)中间件
app.use(bodyParser.json());		//加载bodyParset中间件
app.use(bodyParser.urlencoded({ extended: false }));	//加载解析urlencoded请求体的中间件 
app.use(cookieParser());	//加载解析cookie
app.use(express.static(path.join(__dirname, 'public')));	//设置public为存放静态文件
//设置路由路径
app.use('/', index);	
app.use('/users', users);

//捕捉404错误
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

//开发环境下的错误,将错误渲染到模板显示到浏览器
app.use(function(err, req, res, next) {
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};
  res.status(err.status || 500);
  res.render('error');
});

//暴露这个模块中的app,让其他模块能够使用
module.exports = app;

API 手册 Express 4.X-API

routes

放置路由文件的文件夹。所谓路由,就是对不同路径下的请求导流,导入不同模块进行归类处理。

未特别指出一个文件夹下的路由文件则默认选择为./index文件。

index.js

这个路由的主体

var express = require('express');
var router = express.Router();

//对‘/’url下的GET请求进行处理。即loaclhost:port/地址的响应
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

res.render表示调用index模板文件,并把参数title传到模板文件中 (因为我们在app.js文件中设置了模板为ejs 所以这个找的是view下的index.ejs而不是index.html) 。

express路由的官方文档:Express 路由

users.js

一个测试文件。

var express = require('express');
var router = express.Router();

//对‘/users/’url下的GET请求进行处理。因为在.app中设置的
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

view

存放视图文件的文件夹。视图文件采用的ejs模版。

index.ejs

主页的ejs模版。

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

ejs部分语法:

<% [code]%>可以在里面写js代码。

<%= [code]%>将code内容显示在页面中。

<%- [code]%>显示替换前html的内容。

<%include [x.ejs]%>用来进行布局。

public

存放静态文件,里面有三个文件夹 分别存放img , js ,css等文件。