您的位置:首页 > Web前端 > Node.js

我是怎么构建Node.js程序的

2015-04-21 15:48 288 查看
原文: http://blog.ragingflame.co.za/2015/4/1/how-i-build-nodejs-applications

"保持简单, 保持模块化."

开发步骤

通常是从画一个项目的草图开始. :

分析项目的草图, 理解需要的Domain

创建项目的README文件

基于草图, 在文档中写出路由和 API

创建领域模型

选择软件堆栈和要依赖的Module

设置项目的仓储

写出数据库scheme, 创建数据库

开始编码,写Models 和 Collections

写单元测试

写Controllers 和类库

创建路由

写集成测试

创建API

Review代码, 有必要的话进行调整

架构

我的应用受MVC的影响比较大. MVC 架构非常适合Node.js 开发.

下面是我的典型的目录结构.

/
api/
bin/
collections/
config/
controllers/
env/
lib/
models/
public/
routes/
test/
views/
.gitignore
.jshintrc
app.js
package.json
README.md


下面我们描述下每个文件夹和文件在我们项目目录里的用处.

Documentation (./README.md)

README.md是我项目里非常重要的一个文件
.

我的
README.md
文件包含下面的信息:

项目名和描述

软件要求

依赖

Getting started instructions

需求配置

任务命令

风格指南

应用架构

路由/API

License信息

下面的例子是我怎么描述我的路由的:

/**
*  Routes
**/
GET  /items     - get a collection of items
GET  /items/:id - get one item
POST /items     - save an item


./models

在软件应用中, model通常代表一个数据库表的记录.

./models/mymodel.js

// get config
var config = require('../config');
// connect to the database
var Bookshelf = require('../lib/dbconnect')(config);
// define model
var myModel = Bookshelf.Model.extend({
tableName: 'items'
});
// export collection module
module.exports = myModel;


./collections

Collections 像表一样的一组model. 一个
collection
通常代表一个完整的数据库表.

./collections/mycollection.js

//require the model for this collection
var myModel = require('../models/mymodel');
// define collection
var myCollection = Bookshelf.Collection.extend({
model: myModel
});
// export collection module
module.exports = myCollection;


./controllers

Controllers, 和其他的典型的 MVC 一样, 负责应用的业务逻辑. 我们的controllers根据路由处理数据、查询数据库.

./controllers/items.js

var myModel = require('../models/mymodel');
var myCollection = require('../collections/mycollection');
module.exports = {
// GET /items/:id
getItem: function(req, res, next) {
var id = req.params.id;
myModel.forge({id: id})
.fetch()
.then(function (model) {
res.json(model.toJSON());
})
.otherwise(function (error) {
res.status(500).json({msg: error.message});
});
},
// GET /items
getItems: function(req, res, next) {
var id = req.params.id;
myCollection.forge()
.fetch()
.then(function (collection) {
res.json(collection.toJSON());
})
.otherwise(function (error) {
res.status(500).json({msg: error.message});
});
},
// POST /items
// (Don't forget to validate and sanitize all user input)
saveItem: function(req, res, next) {
myModel.forge(req.body)
.save()
.then(function (model) {
res.json(model.toJSON());
})
.otherwise(function (error) {
res.status(500).json({msg: error.message});
});
}
};


./routes

存放路由.

./routes/items.js

var express = require('express');
var itemsController = require('../controllers/items');
module.exports = function () {
var router = express.Router();
router.get('/items', itemsController.getItems);
router.get('/items/:id', itemsController.getItem);
router.post('/items', itemsController.saveItem);
return router;
};


./config

当我们创建model的时候我们需要config module. config的唯一目的是检查环境类型从env文件夹加载适当的config文件.
config目录只有一个文件
index.js
.

module.exports = (function (env) {
var config = {};
switch (env) {
case 'production':
config = require('../env/production');
break;
case 'development':
config = require('../env/development');
break;
case 'testing':
config = require('../env/testing');
break;
case 'staging':
config = require('../env/staging');
break;
default:
console.error('NODE_ENV environment variable not set');
process.exit(1);
}
return config;
})(process.env.NODE_ENV);


./env

env
目录包含了对应不同环境模式的config文件:
development.js
,
production.js
,
test.js
, and
staging.js
.

Here is an example of one file:

module.exports = {
pg: {
host: '127.0.0.1',
database: 'test',
user: 'test',
password: 'test',
charset: 'utf8'
},
mongodb: {
url: 'mongodb://localhost:27017/test'
},
sessionSecret: 'ninja_cat'
};


注意了: 别在config文件中包含敏感数据, 敏感数据放到环境变量中去

./api

api
文件夹包含应用的api文件. 我用创建controller一样的方法创建api文件, 唯一不同的是controller会加载一个视图文件.

./lib

lib
文件夹在Node modules中非常普遍. 如果你的应用使用了特别的算法或helpers lib目录适合放他们. 在大多数情况下controller需要一个
lib 文件来执行一些特定的任务
.

./bin

bin包含我自己的
command-line scripts. 例如:

#!/usr/bin/env node
console.log('I am an executable file');


./public

public
文件夹包含一些客户端的静态文件, 例如images, css, 前端JavaScript, fonts 等

./views

我所有的视图模板都放在这.

./test

test
目录包含了所有的测试用例.

./.gitignore

.gitignore
文件用来告诉GIT那些文件或者目录不要版本控制.

*.zip
*.psd
*~
node_modules/
bower_components/
build/
temp/


./.jshintrc

.jshintrc
jshint 的配置文件

{
"curly": false,
"eqeqeq": true,
"immed": true,
"latedef": false,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"boss": true,
"eqnull": true,
"node": true,
"browser": true,
"globals": {
"jQuery": true,
"define": true,
"requirejs":true,
"require": true,
"describe": true,
"it": true,
"beforeEach": true,
"before": true
}
}


./package.json

package.json
是一个标准的npm文件, 列出了所有应用的 dependencies 和 metadata.

例子:

{
...
"scripts": {
"start": "node app.js",
"dev": "nodemon app",
"jshint": "jshint api collections config controllers env lib models public/javascripts routes test app.js",
"test": "npm run jshint && mocha test",
"precommit": "npm test",
"prepush": "npm shrinkwrap && npm test",
"postmerge": "npm install"
}
...
}


一些我经常用的 modules

Express - App frameworks

Bookshelf - Postgres 和 MySQL 的 ORM

lodash - 工具类库

passport - 验证

mongoose - MongoDB ODM

when.js - promises library

moment - 分析, 验证, manipulating, 格式化日期

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: