好吧,已经有一段时间了,这是一个很受欢迎的问题,所以我继续创建了一个脚手架github存储库,其中包含JavaScript代码和关于如何构建中型express的长篇自述.js应用程序.
focusaurus/express_code_structure是带有最新代码的回购协议.欢迎拉请求.
这里是自述文件的一个快照,因为stackoverflow不喜欢简单的链接答案.我会做一些更新,因为这是一个新项目,我会继续更新,但最终github repo将是这些信息的最新位置.
Express Code Structure
这个项目是如何组织中型express 的一个例子.js web应用程序.
Current to at least express v4.14 December 2016
你的申请有多大?
Web应用程序并不完全相同,在我看来,没有一种代码 struct 可以应用于所有express.js应用程序.
如果你的应用程序很小,你不需要像这里举例说明的那样有这么深的目录 struct .只需保持简单,在存储库的根目录中插入少量.js
个文件,就完成了.瞧.
如果你的应用程序很大,在某个时候你需要把它分解成不同的npm包.一般来说, node .js方法似乎倾向于使用许多小软件包,至少对于库来说是这样,您应该通过使用几个npm软件包来构建应用程序,因为这开始有意义,并证明了开销的合理性.因此,随着应用程序的增长,部分代码在应用程序之外明显可重用,或者是一个清晰的子系统,请将其移动到自己的git存储库中,并将其变成一个独立的npm包.
So本项目的重点是为中型应用程序演示一个可行的 struct .
你的总体架构是什么
构建web应用程序有很多方法,例如
每一个都很好地适应了不同的目录 struct .就本例而言,它只是一个脚手架,并不是一个完全工作的应用程序,但我假设以下关键架构点:
- 该网站有一些传统的静态页面/模板
- 网站的"应用程序"部分开发为单页应用程序风格
- 应用程序向浏览器公开REST/JSON样式的API
- 该应用程序模拟了一个简单的商业领域,在本例中,它是一个汽车经销商应用程序
那么Ruby on Rails呢?
整个项目的主题是,Ruby on Rails中体现的许多 idea 以及他们所采用的"约定优先于配置"决策,尽管被广泛接受和使用,但实际上并不是很有帮助,有时与该存储库建议的相反.
这里我的主要观点是,组织代码有一些基本原则,基于这些原则,Ruby on Rails约定对Ruby on Rails社区来说(主要)是有意义的.然而,只是轻率地模仿这些惯例就没有抓住重点.一旦你掌握了基本原则,你所有的项目都会井然有序,清晰明了:shell脚本、游戏、移动应用程序、企业项目,甚至你的主目录.
对于Rails社区来说,他们希望能够让一个Rails开发人员在不同的应用之间切换,并且每次都能熟悉和熟悉它.如果你是37个信号或关键实验室,这很有意义,而且有好处.在服务器端JavaScript的世界里,总体的精神状态是更疯狂的,我们对此没有什么问题.我们就是这样滚的.我们已经习惯了.甚至在快车内.js,它是Sinatra的近亲,而不是Rails,从Rails中获取惯例通常没有任何帮助.我甚至会说Principles over Convention over 配置.
基本原则和动机
应用程序符号链接技巧
在great gist Better local require() paths for Node.js中,社区详细介绍和讨论了许多方法.我可能很快就会决定 Select "只是处理大量的…./../...."或者使用requireFrom模式.然而,目前,我一直在使用下面详述的符号链接技巧.
因此,一种避免项目内需要使用恼人的相对路径(如require("../../../config")
)的方法是使用以下技巧:
- 在应用程序的 node _模块下创建一个符号链接
- 将just the node_modules/app symlink itself,而不是整个node_modules文件夹添加到git
- Now you can require intra-project modules using this prefix
var config = require("app/config");
var DealModel = require("app/deals/deal-model")
;
- 基本上,这使得项目内部所需的工作与外部npm模块的工作非常相似.
- 抱歉,Windows用户,您需要坚持使用父目录相对路径.
配置
通常,对模块和类进行编码,使其只需要传入一个基本的JavaScript options
对象.只有app/server.js
应该加载app/config.js
模块.从那里,它可以合成options
个小对象来根据需要配置子系统,但将每个子系统耦合到一个充满额外信息的大型全局配置模块是不好的耦合.
try 集中创建数据库连接并将其传递到子系统,而不是传递连接参数并让子系统自己进行传出连接.
NODE_ENV
这是Rails带来的另一个诱人但可怕的 idea .你的应用程序中应该只有一个位置,app/config.js
,用于查看NODE_ENV
环境变量.其他一切都应该使用显式选项作为类构造函数参数或模块配置参数.
如果邮箱模块有一个关于如何发送邮箱的选项(SMTP、登录到stdout、放入队列等),那么它应该 Select 像{deliver: 'stdout'}
这样的选项,但绝对不应该 Select NODE_ENV
.
测验
现在,我将测试文件与其对应的代码保存在同一目录中,并使用文件扩展名命名约定来区分测试和生产代码.
foo.js
有模块"foo"的代码
foo.tape.js
具有基于 node 的foo测试,并且位于同一目录中
foo.btape.js
可用于需要在浏览器环境中执行的测试
我使用文件系统globs和find . -name '*.tape.js'
命令来访问所有必要的测试.
How to organize code within each .js
module file
这个项目的范围主要是关于文件和目录的位置,我不想添加太多其他范围,但我只想提到,我将代码组织成3个不同的部分.
- 打开CommonJS块需要调用状态依赖项
- 纯JavaScript的主代码块.这里没有污染.不要引用导出、模块或要求.
- 关闭CommonJS块以设置导出