我正在为 NodeJS 使用 ExpressJS Web 框架。
使用 ExpressJS 的人将他们的环境(开发、生产、测试......)、他们的路线等放在app.js. 我认为这不是一个漂亮的方式,因为当你有一个大的应用程序时,app.js 太大了!
app.js
我想要这个目录结构:
| my-application | -- app.js | -- config/ | -- environment.js | -- routes.js
这是我的代码:
应用程序.js
var express = require('express'); var app = module.exports = express.createServer(); require('./config/environment.js')(app, express); require('./config/routes.js')(app); app.listen(3000);
配置/环境.js
module.exports = function(app, express){ app.configure(function() { app.use(express.logger()); }); app.configure('development', function() { app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); app.configure('production', function() { app.use(express.errorHandler()); }); };
配置/routes.js
module.exports = function(app) { app.get('/', function(req, res) { res.send('Hello world !'); }); };
我的代码运行良好,我认为目录的结构很漂亮。但是,必须修改代码,我不确定它是否好/漂亮。
使用我的目录结构并调整代码还是只使用一个文件(app.js)更好?
感谢您的建议!
好的,已经有一段时间了,这是一个流行的问题,所以我继续创建了一个脚手架 github 存储库,其中包含 JavaScript 代码和一个关于我喜欢如何构建中型 express.js 应用程序的长自述文件。
focusaurus/express_code_structure是带有最新代码的仓库。欢迎拉取请求。
这是自述文件的快照,因为 stackoverflow 不喜欢只是一个链接的答案。我会做一些更新,因为这是一个我会继续更新的新项目,但最终 github 存储库将是此信息的最新位置。
该项目是如何组织中型 express.js Web 应用程序的示例。
当前至少表达 v4.14 December 2016
Web 应用程序并不完全相同,在我看来,不存在应该应用于所有 express.js 应用程序的单一代码结构。
如果您的应用程序很小,则不需要此处示例的如此深的目录结构。只需保持简单并将少量.js文件粘贴到存储库的根目录中即可。脿。
.js
如果您的应用程序很大,有时您需要将其分解为不同的 npm 包。一般来说,node.js 方法似乎有利于许多小包,至少对于库而言,并且您应该使用多个 npm 包来构建您的应用程序,因为这开始变得有意义并证明开销是合理的。因此,随着您的应用程序增长并且某些部分代码在您的应用程序之外变得明显可重用或者是一个明确的子系统,请将其移动到它自己的 git 存储库并使其成为一个独立的 npm 包。
所以 这个项目的重点是说明一个中型应用程序的可行结构。
构建 Web 应用程序的方法有很多,例如
这些中的每一个都很好地适合不同的目录结构。出于本示例的目的,它只是一个脚手架,而不是一个完全工作的应用程序,但我假设以下关键架构点:
Ruby on Rails 中体现的许多想法以及他们采用的“约定优于配置”决策将成为整个项目的一个主题,虽然被广泛接受和使用,但实际上并不是很有帮助,有时与这个存储库的相反建议。
我的主要观点是组织代码有一些基本原则,基于这些原则,Ruby on Rails 约定(大部分)对 Ruby on Rails 社区有意义。然而,只是漫不经心地模仿这些惯例,就没有抓住重点。一旦您掌握了基本原则,您的所有项目都将井然有序且清晰:shell 脚本、游戏、移动应用程序、企业项目,甚至您的主目录。
对于 Rails 社区,他们希望能够让一个 Rails 开发人员从一个应用程序切换到另一个应用程序,并且每次都熟悉和适应它。如果您是 37 个信号或 Pivotal Labs,这很有意义,并且有好处。在服务器端的 JavaScript 世界中,整体的精神是更加狂野的西部任何事情都发生了,我们对此并没有真正的问题。我们就是这样滚动的。我们已经习惯了。即使在 express.js 中,它也是 Sinatra 的近亲,而不是 Rails,并且从 Rails 中获取约定通常无济于事。我什至会说 Principles over Convention over Configuration 。
app/node_modules
package.json
app
cd
kebab-case
camelCase
-
app/views
app/controllers
app/models
routes.rb
app/users
app/server.js:1
magicRESTRouter.route(somecontroller, {except: 'POST'})
app.get``app.put``app.del
使用小写的kebab文件名
不要使用app.configure. 它几乎完全没用,你只是不需要它。由于盲目的copypasta,它在很多样板中。
app.configure
中间件和路由的顺序!
app.use
body-parser
server.js
社区在“更好的 Node.js 本地 require() 路径”中详细概述和讨论了许多方法。我可能很快会决定选择“只处理大量 ../../../..”或使用requireFrom模块。但是,目前,我一直在使用下面详述的符号链接技巧。
因此,避免项目内需要使用烦人的相对路径的一种方法require("../../../config")是使用以下技巧:
require("../../../config")
.gitignore
var config = require("app/config");
var DealModel = require("app/deals/deal-model")
通常代码模块和类只期望options传入一个基本的 JavaScript 对象。只app/server.js应该加载app/config.js模块。从那里它可以合成小options对象以根据需要配置子系统,但是将每个子系统耦合到一个充满额外信息的大型全局配置模块是不好的耦合。
options
app/server.js
app/config.js
尝试集中创建数据库连接并将其传递给子系统,而不是传递连接参数并让子系统自己建立传出连接。
这是从 Rails 继承而来的另一个诱人但可怕的想法。您的应用程序中应该恰好有 1 个位置app/config.js查看NODE_ENV环境变量。其他一切都应采用显式选项作为类构造函数参数或模块配置参数。
NODE_ENV
如果电子邮件模块有关于如何发送电子邮件的选项(SMTP、登录到标准输出、放入队列等),它应该采用类似{deliver: 'stdout'}但绝对不应该检查的选项NODE_ENV。
{deliver: 'stdout'}
我现在将我的测试文件与其对应的代码保存在同一目录中,并使用文件扩展名命名约定来区分测试和生产代码。
foo.js
foo.tape.js
foo.btape.js
我根据需要使用文件系统 glob 和find . -name '*.tape.js'命令来访问我的所有测试。
find . -name '*.tape.js'
这个项目的范围主要是关于文件和目录的去向,我不想添加太多其他范围,但我只想提一下,我将我的代码组织成 3 个不同的部分。