Суть таква: node.js не дает готового решения для создания проекта. Первый мой проект на node.js состоял из одного coffeescript файла и run.js для запуска из IDE. Когда роутов было пять штук все было замечательно, но когда проект оброс моделями и роутерами это превратилось в ад. Решают эту проблему разными способами, кто-то используй hub, кто-то global, кто-то все в один фаил заносит.
Внимание: решение не претендует быть единственным правильным и вообще правильным. Просто решил поделиться. Срач на тему node.js vs erlang прошу не разводить, они в разных категориях.
Для не терпеливых есть проект на гитхабе.
MR — Model Route, View я опускаю потому, что res.json это не view, а сервису большего и не надо.
Структура проекта:
├── app.coffee
├── config.coffee
├── models
│ └── example.coffee
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
├── routes
│ ├── index.coffee
│ └── root.coffee
├── run-cluster.js
└── run.js
app.coffee
В этом это точка входа в приложение.
exports.start = () ->
log = require('logule') # Удобный логер
log.debug "Spawning new worker"
require 'coffee-script' # нужно для того, чтобы нода переваривала .coffee файлы в require
###
Basic dependencies
###
express = require 'express'
app = module.exports = express.createServer()
app.__ = require 'underscore' # на всякий случай
app.mongoose = require 'mongoose' # ODM для MongoDb, and yes, it's web scale
app.log = log # костыль
config = require('./config.coffee')(app,express) # конфигурация приложения
models = {} # Сюда складываются все модели
models.example= require('./models/example')(app.mongoose).model # Пример модели
require('./routes/index.coffee')(app, models) # Фаил в котором прописаны все маршруты
port = process.env.PORT || 5000 # Для Heroku и других схем деплоя
app.listen port
log.info "Express server listening on port #{port}"
config.coffee
module.exports = (app, express) ->
config = this
app.configure ->
app.use express.bodyParser()
app.use express.methodOverride()
app.use app.router
app.use express.static(__dirname + '/public')
app.configure 'development', () ->
app.use express.errorHandler({dumpExveption: true, showStack: true}) # "полезный" дамп стека
app.mongoose.connect process.env.MONGOLAB_URI || "mongodb://localhost/skel" # Для heroku
app.configure 'production', () ->
app.use express.errorHandler()
app.mongoose.connect "mongodb://localhost/production"
return config
models/example.coffee
module.exports = (mongoose) ->
Schema = mongoose.Schema
ObjectId = Schema.ObjectId
#Comment = mogoose.model('Comment') # пример того как получить модель которая уже ассоциирована с mongoose.
PostSchema = new Schema {
author : { type:ObjectId, index:true }
date : Date,
content : String
#, comments : [Comment] # пример того как ее использовать
}
this.model = mongoose.model('Post', PostSchema) # ассоциирование
return this
package.json
engines секция это для Heroku, все остальное понятно.
{
"name": "mr-skel"
, "version": "0.0.1"
, "private": true
, "engines": {
"node": "0.6.x",
"npm": "1.x.x"
}
, "dependencies": {
"express": "2.5.x"
, "mongoose": "2.6.x"
, "mongoose-types": "*"
, "underscore": "*"
, "coffee-script": "*"
, "logule": "0.x.x"
},
"devDependencies": {
"forever": "*"
, "mocha": "*"
, "should": "*"
}
}
routes/index.coffee
В этом файле хранятся все роуты которые есть в приложении.
routes = {}
routes.root = require('./root.coffee')
module.exports = (app, models) ->
app.get '/', routes.root.getIndex(models) # Насамом деле это костыль, я не смогу придумать как сделать models доступной для всех роутов из root.cofee
routes/root.coffee
exports.getIndex = (models) ->
(req, res) ->
Post = models.example
Post.find {}, (err, posts) ->
if err?
return res.send 500
res.json { status: 'Ba dum tssh', meta: posts }
run-cluster.js
Запуск приложения при помощи Cluster API. На Heroku не работает, однако, на своей
cluster = require('cluster');
log = require('logule');
require('coffee-script');
if (cluster.isMaster) {
log.info("Master have just started");
# i = кол-во ядер
for (i = 1; i <= 2; i++) {
cluster.fork();
}
cluster.on('death', function(worker) {
log.error("Worker " + worker.pid + " died!");
return cluster.fork();
});
} else {
app = require('./app.coffee');
app.start()
}
run.js
require('coffee-script');
app = require('./app.coffee');
app.start();
Автор: Zelgadis