[译]我是怎么构建Node.js程序的
原文: 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, 格式化日期
[译]我是怎么构建Node.js程序的的更多相关文章
- 在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure
[题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在 ...
- [译]How to Install Node.js on Ubuntu 14.04 如何在ubuntu14.04上安装node.js
原文链接为 http://www.hostingadvice.com/how-to/install-nodejs-ubuntu-14-04/ 由作者Jacob Nicholson 发表于October ...
- 玩儿转物联网IoT - 在Beagle Bone Black上运行node.js 程序
物联网(IoT)技术方兴未艾,智能手环,智能血压计,智能眼镜甚至智能鞋垫都开始进入我们的生活,各种智能设备层出不穷,世界已经到了一个"人有多大胆,地有多大产"的时代,不玩儿点物联网 ...
- 在Visual Studio上开发Node.js程序
[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio ...
- 使用events.EventEmitter 控制Node.js 程序执行流程
使用events.EventEmitter 控制Node.js 程序执行流程 标题写的可能也不太对,大家领会精神: Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. ...
- 一种简单的生产环境部署Node.js程序方法
最近在部署Node.js程序时,写了段简单的脚本,发觉还挺简单的,忍不住想与大家分享. 配置文件 首先,本地测试环境和生产环境的数据库连接这些配置信息是不一样的,需要将其分开为两个文件存储 到conf ...
- Node.js程序在node-windows中不能运行
Node.js程序部分功能在命令行中运行良好,但在node-windows中不能运行,怎么回事? 答:路径问题. 请看如下的描述: My script runs fine on it's own, ...
- 在Visual Studio 2013 上开发Node.js程序
[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio ...
- 3.第一个Node.js程序:Hello World!
转自:http://www.runoob.com/nodejs/nodejs-tutorial.html 以下是我们的第一个Node.js程序: console.log("Hello Wor ...
随机推荐
- 关于git的学习
Git是目前世界上最先进的分布式版本控制系统(没有之一)! 由于现在用的还不多,还没有这种体会,但是前人的经验是值得借鉴的,所以我认真的学习了一些关于git的简单操作,现在在这分享一些心得,或者说是为 ...
- 个人作业—Week3
博客阅读体会 阅读了十几位软件工程师前辈的博文,了解了前辈们作为一名软件工程师的成长经历,我有一些感触. 这十几位前辈们的经历有着很大的差别,有的科班出身,有的则完全自学成才.不同的经历使得前辈们看问 ...
- 【Alpha阶段】第六次Scrum例会
会议信息 时间:2016.10.27 21:30 时长:30min 地点:大运村1号公寓5楼楼道 类型:日常Scrum会议 个人任务报告 姓名 今日已完成Issue 明日计划Issue 工作困难 今日 ...
- 【原】webpack结合gulp打包
在我前面的文章中,总结了一下自己学习webpack和gulp的一些东西.然而,在我的实际项目中,单独使用它们两者不能满足项目的需求.我遇到了下面的一些问题. 问题1: 因为我的图片需要放单cdn上面去 ...
- uC/OS-II互斥信号(OS_mutex)块
/*************************************************************************************************** ...
- win7下exe提示无法正常启动(0xc0000906)
本人遇见是 avast问题,卸了
- ArcGIS Server开发教程系列(8)ArcGIS API for Javascript-控件(小部件)(续)纯代码
完整代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/ht ...
- sublime2的快捷键
1.快速文件转换 与sublime2中搜索文件快捷键一样,ctrl+p ctrl + p //window comm + p //mac 2.在代码中搜索 在所有已加载的文件中查找一个特定的字符串,支 ...
- getElement的几中属性介绍
1.getElementById("a"); 获取div的id (注意:getElementById 是没有s的,getElementsByTagName()是带s的) 这种 ...
- lamp环境搭建(ubuntu)
系统:Ubuntu14.04 方法一.最简单的在线安装 (参考网址:http://os.51cto.com/art/201307/405333.htm) 具体过程: [1]打开终端,执行命令 # su ...