Is there a common convention for breaking up and modularizing the app.js
file in an Express.js application? Or is it common to keep everything in a single file?
在Express中,是否有一种常见的分解和模块化app.js文件的惯例。js应用程序?还是把所有东西都保存在一个文件中很常见?
3 个解决方案
#1
81
I have mine broken up as follows:
我的分手理由如下:
~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
| |-new.jade
| |-_form.jade
|~test
| |~controllers
| |-zoo.js
| |~models
| |-zoo.js
|-index.js
I use Exports to return what's relevant. For instance, in the models I do:
我使用导出返回相关的内容。例如,在我的模型中:
module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);
and then if I need to create a phone number, it's as simple as:
如果我需要创建一个电话号码,很简单:
var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();
if I need to use the schema, then PhoneNumber.schema
如果我需要使用模式,那么PhoneNumber.schema
(which assumes that we are working from the routes folder and need to go 1 level up and then down to models)
(假设我们在route文件夹中工作,需要从上一级到下一级到模型)
EDIT 4
The express wiki has a list of frameworks built on top of it.
express wiki上面有一个框架列表。
Of those, I think Twitter's matador is structured pretty well. We actually used a very similar approach to how they load up parts of the app.
其中,我认为Twitter的斗牛士结构很好。我们实际上使用了一个非常相似的方法来加载应用程序的部分。
derby.js also looks extremely interesting. It's akin to meteor without all of the hype and actually gives credit where credit is due (notably, node and express).
德比。js看起来也非常有趣。它类似于《流星》,没有大肆宣传,而是在值得赞扬的地方给予赞扬(值得注意的是,node和express)。
EDIT 3
If you are a fan of CoffeeScript (I am not) and reeeeaaaaaally want the L&F of Rails, there is also Tower.js.
如果你是一个咖啡爱好者(我不是),并且reeeeaaaaaally想要的是Rails的L&F,也有Tower.js。
EDIT 2
If you are familiar with Rails and don't mind the bleed-over of some concepts there is Locomotive. It is a light-weight framework built on Express. It has a very similar structure as RoR and carries over some of the more rudimentary concepts (such as routing).
如果您熟悉Rails,并且不介意某些概念的简化,那么这里就有火车头。这是一个基于Express的轻量级框架。它的结构与RoR非常相似,并且包含一些更基本的概念(如路由)。
It's worth checking out even if you don't plan to use it.
即使你不打算使用它,也值得一试。
EDIT 1
nodejs-express-mongoose-demo is very similar to how I have mine structured. Check it out.
nodejs-express-mongoose-demo非常类似于我的结构。检查出来。
#2
8
Warning: referencing code I hacked together for node knockout, it kind of works but is far from elegant or polished.
警告:引用的代码我一起攻击了node knockout,它是一种工作,但远不是优雅或优雅。
To be more specific about splitting up app.js
I have the following app.js file
关于拆分app.js,我有下面的app.js文件
var express = require('express'),
bootstrap = require('./init/bootstrap.js'),
app = module.exports = express.createServer();
bootstrap(app);
This basically means I place all my bootstrapping in a seperate file, then I bootstrap the server.
这基本上意味着我将所有的引导放在一个独立的文件中,然后引导服务器。
So what does bootstrap do?
那么bootstrap做什么呢?
var configure = require("./app-configure.js"),
less = require("./watch-less.js"),
everyauth = require("./config-everyauth.js"),
routes = require("./start-routes.js"),
tools = require("buffertools"),
nko = require("nko"),
sessionStore = new (require("express").session.MemoryStore)()
module.exports = function(app) {
everyauth(app);
configure(app, sessionStore);
less();
routes(app, sessionStore);
nko('/9Ehs3Dwu0bSByCS');
app.listen(process.env.PORT);
console.log("server listening on port xxxx");
};
Well it splits all the server initialization setup in nice chunks. Specifically
它将所有的服务器初始化设置分割成漂亮的块。具体地说
- I have a chunk that sets up all my remote OAuth authentication using everyauth.
- 我有一个使用everyauth设置所有远程OAuth身份验证的块。
- I have a chunk that configures my application (basically calling
app.configure
) - 我有一个配置应用程序的块(基本上是调用app.configure)
- I have a little bit of code that punches less so it re-compiles any of my less into css at run time.
- 我有一些代码,可以减少输入,以便在运行时重新编译css。
- I have code that sets up all my routes
- 我有设置所有路径的代码
- I call this small nko module
- 我称之为小型的nko模块
- Finally I start the server by listening to a port.
- 最后,我通过监听一个端口来启动服务器。
Just for example let's look at the routing file
例如,让我们看一下路由文件
var fs = require("fs"),
parseCookie = require('connect').utils.parseCookie;
module.exports = function(app, sessionStore) {
var modelUrl = __dirname + "/../model/",
models = fs.readdirSync(modelUrl),
routeUrl = __dirname + "/../route/"
routes = fs.readdirSync(routeUrl);
Here I load all my models and routes as arrays of files.
在这里,我将所有的模型和路由都加载到文件数组中。
Disclaimer: readdirSync
is only ok when called before you start the http server (before .listen
). Calling synchronious blocking calls at server start time just makes the code more readable (it's basically a hack)
免责声明:只有在启动http服务器(在.listen之前)之前调用readdirSync时才ok。在服务器启动时调用同步阻塞调用只会使代码更可读(它基本上是一个hack)
var io = require("socket.io").listen(app);
io.set("authorization", function(data, accept) {
if (data.headers.cookie) {
data.cookie = parseCookie(data.headers.cookie);
data.sessionId = data.cookie['express.sid'];
sessionStore.get(data.sessionId, function(err, session) {
if (err) {
return accept(err.message, false);
} else if (!(session && session.auth)) {
return accept("not authorized", false)
}
data.session = session;
accept(null, true);
});
} else {
return accept('No cookie', false);
}
});
Here I punch socket.io to actually use authorization rather then letting any tom and jack to talk to my socket.io server
在这里我打孔套接字。io .使用授权,而不是让tom和jack跟我的插座说话。io服务器
routes.forEach(function(file) {
var route = require(routeUrl + file),
model = require(modelUrl + file);
route(app, model, io);
});
};
Here I start my routes by passing the relevant model into each route object returned from the route file.
在这里,我通过将相关模型传递到从route文件返回的每个route对象开始路由。
Basically the jist is you organize everything into nice little modules and then have some bootstrapping mechanism.
基本的第一步是你把所有东西组织成漂亮的小模块,然后有一些引导机制。
My other project (my blog) has an init file with a similar structure.
我的另一个项目(我的博客)有一个类似结构的init文件。
Disclaimer: the blog is broken and doesn't build, I'm working on it.
免责声明:博客被破坏了,没有建立,我正在努力。
#3
1
For maintainable routing organisation you can check out this article about the express-routescan node module and try it. This is the best solution for me.
对于可维护的路由组织,您可以查看这篇关于express-routescan节点模块的文章并尝试一下。这对我来说是最好的解决办法。
#1
81
I have mine broken up as follows:
我的分手理由如下:
~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
| |-new.jade
| |-_form.jade
|~test
| |~controllers
| |-zoo.js
| |~models
| |-zoo.js
|-index.js
I use Exports to return what's relevant. For instance, in the models I do:
我使用导出返回相关的内容。例如,在我的模型中:
module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);
and then if I need to create a phone number, it's as simple as:
如果我需要创建一个电话号码,很简单:
var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();
if I need to use the schema, then PhoneNumber.schema
如果我需要使用模式,那么PhoneNumber.schema
(which assumes that we are working from the routes folder and need to go 1 level up and then down to models)
(假设我们在route文件夹中工作,需要从上一级到下一级到模型)
EDIT 4
The express wiki has a list of frameworks built on top of it.
express wiki上面有一个框架列表。
Of those, I think Twitter's matador is structured pretty well. We actually used a very similar approach to how they load up parts of the app.
其中,我认为Twitter的斗牛士结构很好。我们实际上使用了一个非常相似的方法来加载应用程序的部分。
derby.js also looks extremely interesting. It's akin to meteor without all of the hype and actually gives credit where credit is due (notably, node and express).
德比。js看起来也非常有趣。它类似于《流星》,没有大肆宣传,而是在值得赞扬的地方给予赞扬(值得注意的是,node和express)。
EDIT 3
If you are a fan of CoffeeScript (I am not) and reeeeaaaaaally want the L&F of Rails, there is also Tower.js.
如果你是一个咖啡爱好者(我不是),并且reeeeaaaaaally想要的是Rails的L&F,也有Tower.js。
EDIT 2
If you are familiar with Rails and don't mind the bleed-over of some concepts there is Locomotive. It is a light-weight framework built on Express. It has a very similar structure as RoR and carries over some of the more rudimentary concepts (such as routing).
如果您熟悉Rails,并且不介意某些概念的简化,那么这里就有火车头。这是一个基于Express的轻量级框架。它的结构与RoR非常相似,并且包含一些更基本的概念(如路由)。
It's worth checking out even if you don't plan to use it.
即使你不打算使用它,也值得一试。
EDIT 1
nodejs-express-mongoose-demo is very similar to how I have mine structured. Check it out.
nodejs-express-mongoose-demo非常类似于我的结构。检查出来。
#2
8
Warning: referencing code I hacked together for node knockout, it kind of works but is far from elegant or polished.
警告:引用的代码我一起攻击了node knockout,它是一种工作,但远不是优雅或优雅。
To be more specific about splitting up app.js
I have the following app.js file
关于拆分app.js,我有下面的app.js文件
var express = require('express'),
bootstrap = require('./init/bootstrap.js'),
app = module.exports = express.createServer();
bootstrap(app);
This basically means I place all my bootstrapping in a seperate file, then I bootstrap the server.
这基本上意味着我将所有的引导放在一个独立的文件中,然后引导服务器。
So what does bootstrap do?
那么bootstrap做什么呢?
var configure = require("./app-configure.js"),
less = require("./watch-less.js"),
everyauth = require("./config-everyauth.js"),
routes = require("./start-routes.js"),
tools = require("buffertools"),
nko = require("nko"),
sessionStore = new (require("express").session.MemoryStore)()
module.exports = function(app) {
everyauth(app);
configure(app, sessionStore);
less();
routes(app, sessionStore);
nko('/9Ehs3Dwu0bSByCS');
app.listen(process.env.PORT);
console.log("server listening on port xxxx");
};
Well it splits all the server initialization setup in nice chunks. Specifically
它将所有的服务器初始化设置分割成漂亮的块。具体地说
- I have a chunk that sets up all my remote OAuth authentication using everyauth.
- 我有一个使用everyauth设置所有远程OAuth身份验证的块。
- I have a chunk that configures my application (basically calling
app.configure
) - 我有一个配置应用程序的块(基本上是调用app.configure)
- I have a little bit of code that punches less so it re-compiles any of my less into css at run time.
- 我有一些代码,可以减少输入,以便在运行时重新编译css。
- I have code that sets up all my routes
- 我有设置所有路径的代码
- I call this small nko module
- 我称之为小型的nko模块
- Finally I start the server by listening to a port.
- 最后,我通过监听一个端口来启动服务器。
Just for example let's look at the routing file
例如,让我们看一下路由文件
var fs = require("fs"),
parseCookie = require('connect').utils.parseCookie;
module.exports = function(app, sessionStore) {
var modelUrl = __dirname + "/../model/",
models = fs.readdirSync(modelUrl),
routeUrl = __dirname + "/../route/"
routes = fs.readdirSync(routeUrl);
Here I load all my models and routes as arrays of files.
在这里,我将所有的模型和路由都加载到文件数组中。
Disclaimer: readdirSync
is only ok when called before you start the http server (before .listen
). Calling synchronious blocking calls at server start time just makes the code more readable (it's basically a hack)
免责声明:只有在启动http服务器(在.listen之前)之前调用readdirSync时才ok。在服务器启动时调用同步阻塞调用只会使代码更可读(它基本上是一个hack)
var io = require("socket.io").listen(app);
io.set("authorization", function(data, accept) {
if (data.headers.cookie) {
data.cookie = parseCookie(data.headers.cookie);
data.sessionId = data.cookie['express.sid'];
sessionStore.get(data.sessionId, function(err, session) {
if (err) {
return accept(err.message, false);
} else if (!(session && session.auth)) {
return accept("not authorized", false)
}
data.session = session;
accept(null, true);
});
} else {
return accept('No cookie', false);
}
});
Here I punch socket.io to actually use authorization rather then letting any tom and jack to talk to my socket.io server
在这里我打孔套接字。io .使用授权,而不是让tom和jack跟我的插座说话。io服务器
routes.forEach(function(file) {
var route = require(routeUrl + file),
model = require(modelUrl + file);
route(app, model, io);
});
};
Here I start my routes by passing the relevant model into each route object returned from the route file.
在这里,我通过将相关模型传递到从route文件返回的每个route对象开始路由。
Basically the jist is you organize everything into nice little modules and then have some bootstrapping mechanism.
基本的第一步是你把所有东西组织成漂亮的小模块,然后有一些引导机制。
My other project (my blog) has an init file with a similar structure.
我的另一个项目(我的博客)有一个类似结构的init文件。
Disclaimer: the blog is broken and doesn't build, I'm working on it.
免责声明:博客被破坏了,没有建立,我正在努力。
#3
1
For maintainable routing organisation you can check out this article about the express-routescan node module and try it. This is the best solution for me.
对于可维护的路由组织,您可以查看这篇关于express-routescan节点模块的文章并尝试一下。这对我来说是最好的解决办法。