一个Node.js项目的文件夹结构

400

我注意到Node.js项目经常包含这些文件夹:

/libs, /vendor, /support, /spec, /tests

它们具体是什么意思呢?它们之间有什么不同,以及我应该把引用的代码放在哪里?

7个回答

492

关于您提到的文件夹:

  • /libs 通常用于自定义的 classes/functions/modules
  • /vendor/support 包含第三方库(在使用git作为源代码控制系统时,作为git子模块添加)
  • /spec 包含BDD测试规范。
  • /tests 包含应用程序的单元测试(使用测试框架,请参见这里

注意:自NPM引入干净的包管理以来,/vendor/support 都已被弃用。建议使用NPM和package.json文件处理所有第三方依赖项

在构建相当大的应用程序时,特别是如果您使用一些MVC / ORM框架(如expressmongoose)时,我建议使用以下附加文件夹:

  • /models 包含所有ORM模型(在mongoose中称为Schemas
  • /views 包含您的视图模板(使用express支持的任何模板语言)
  • /public 包含所有静态内容(图像、样式表、客户端JavaScript)
    • /assets/images 包含图像文件
    • /assets/pdf 包含静态PDF文件
    • /css 包含样式表(或由CSS引擎编译的输出)
    • /js 包含客户端JavaScript
  • /controllers 包含了所有应用的模块/区域的 express 路由(注意:当使用 express 的引导功能时,此文件夹名为 /routes
  • 我习惯以这种方式组织我的项目,而且我认为它非常有效。

    针对使用 connect-assets 的基于 CoffeeScript 的 Express 应用程序的更新:

    • /app 包含你编译后的 JavaScript 代码
    • /assets/ 包含了需要编译的所有客户端资源
      • /assets/js 包含你的客户端 CoffeeScript 文件
      • /assets/css 包含了所有 LESS/Stylus 样式表
    • /public/(js|css|img) 包含了所有静态文件,不受任何编译器处理
    • /src 包含了所有服务端特定的 CoffeeScript 文件
    • /test 包含了所有单元测试脚本(使用你选择的测试框架实现)
    • /views 包含了所有 express 视图(无论是 jade、ejs 还是其他任何模板引擎)

    5
    你会将客户端的JS、CSS和图像放在哪里?你是否建议在公共文件夹中使用类似的文件夹结构,例如:public/assets public/assets/css public/assets/images public/assets/docspublic/libs public/support public/tests public/models public/views public/controllers? - ezmilhouse
    2
    ExpressJS会创建一个./routes目录,这和你的示例中的./controllers是一样的吗? - chovy
    2
    为什么不使用该提案创建一个Yeoman生成器呢?这可能会成为一种标准。 - Jayr Motta
    从ASP.NET MVC来看,将“routes”文件夹称为“controllers”对我来说更有意义。 - adam0101
    问题是,目录结构通常是由框架(例如 PHP 的 Symfony)生成的,对吗?例如,使用 Express 时,不会创建目录结构,开发人员需要手动创建和维护 MVC 设计和路由,对吗?感谢任何反馈,我是 Express 的新手。 - AnchovyLegend
    显示剩余6条评论

    58

    有一个类似于这个问题的讨论在GitHub上: https://gist.github.com/1398757

    你可以查找其他项目以作为指导,在GitHub中搜索以下内容:

    • ThreeNodes.js - 我认为,它具有特定结构,不适用于所有项目;
    • lighter - 结构更加简单,但缺乏一些组织性;

    最后,在书籍中(http://shop.oreilly.com/product/0636920025344.do)建议使用以下结构:

    ├── index.html
    ├── js/
    │   ├── main.js
    │   ├── models/
    │   ├── views/
    │   ├── collections/
    │   ├── templates/
    │   └── libs/
    │       ├── backbone/
    │       ├── underscore/
    │       └── ...
    ├── css/
    └── ...
    

    我创建了一个模块来动态地要求文件,使您可以按功能而不是典型的模型、视图、控制器来构建项目。希望它能帮助到某些人:https://github.com/ssmereka/crave - Scott

    27

    你可以在我的项目架构中看到更多的示例,链接在此处:

    ├── Dockerfile
    ├── README.md
    ├── config
    │   └── production.json
    ├── package.json
    ├── schema
    │   ├── create-db.sh
    │   ├── db.sql
    ├── scripts
    │   └── deploy-production.sh 
    ├── src
    │   ├── app -> Containes API routes
    │   ├── db -> DB Models (ORM)
    │   └── server.js -> the Server initlializer.
    └── test
    

    基本上,逻辑应用程序被分离到SRC目录下的DB和APP文件夹中。


    如果您的应用程序还包含一个前端应用程序,您会将其放在src下还是前端应用程序会有自己的文件夹(带有自己的package.json和类似的文件夹结构)? - wal
    3
    @wal,我倾向于将前端项目分离到另一个代码库中,因为这样更有组织性。 - Daniel Chernenkov

    16

    假设我们正在讨论Web应用程序和构建API:

    其中一种方法是通过功能将文件进行分类。 举个例子:


    我们正在开发一个图书馆应用程序。 在应用程序的第一个版本中,用户可以:

    • 搜索图书并查看图书元数据
    • 搜索作者并查看他们的图书

    在第二个版本中,用户还可以:

    • 创建帐户并登录
    • 借出/借入书籍

    在第三个版本中,用户还可以:

    • 保存想要阅读/标记为喜欢的书籍列表

    首先,我们有以下结构:

    books
      └─ entities
      │   └─ book.js
      │   └─ author.js
      │
      └─ services
      │   └─ booksService.js
      │   └─ authorsService.js
      │
      └─ repositories
      │   └─ booksRepository.js
      │   └─ authorsRepository.js
      │
      └─ controllers
      │   └─ booksController.js
      │   └─ authorsController.js
      │
      └─ tests
          └─ ...
    

    我们随后添加了用户和贷款特征:
    user
      └─ controllers
      └─ entities
      └─ services
      └─ ...
    
    loan
      └─ controllers
      └─ ...
    

    接下来是收藏夹功能:

    favorites
      └─ controllers
      └─ entities
      └─ ...
    

    当新开发人员接手将图书搜索功能添加到收藏夹,以便返回标记为收藏的书籍信息时,很容易看到他/她应该查找代码的位置。

    然后当产品所有者进入并宣布应该完全删除收藏功能时,很容易将其删除。


    在这样的结构中,您会将数据库逻辑放在哪里?由于支持存储库的数据库可能对书籍和用户都是共同的,所以它是否最终有自己的文件夹? - castro
    @castro 我认为数据库连接并不特定于某个功能。例如,如果您有一个 SQL 数据库,其中大多数实体都存储在其中,您可以将该逻辑存储在 src/db.js 中。如果您有多个数据存储,则可能 src/infrastructure/ 文件夹中的每个存储的逻辑都是有意义的。 - maxpaj
    1
    可以考虑采用 books.repository.js 命名方案。 - zr0gravity7
    1
    虽然这样做有一些好处,但也存在缺点,比如跨层的通用代码放置不方便。例如,模型的常见插件或控制器的中间件。你最终不得不将它们全部提升到某个公共的src文件夹中,这使得组织变得更加困难,而不是将其整洁地保留在各自的层文件夹中。 - zr0gravity7

    4
    需要翻译的内容:

    值得注意的是,目前并没有一致的意见认为哪种方法和相关框架最好,通常也不会强制或奖励特定的结构。

    我觉得这很令人沮丧,也是一个巨大的负担,但同样重要。它有点像样式指南问题的缩水版本(但在我看来更重要)。我想指出这一点,因为答案是一样的:只要定义明确、连贯就无所谓使用哪种结构

    因此,我建议寻找一份全面的指南,并明确指出该项目基于此。

    这并不容易,特别是对于新手来说!你需要花费几个小时进行研究。你会发现大多数指南都推荐类似MVC的结构。虽然几年前这可能是一个可靠的选择,但现在情况并非如此。例如这里有另一种方法


    2
    这是一个间接回答,关于文件夹结构本身,与之密切相关。
    几年前,我也有同样的问题,采用了一个文件夹结构,但后来不得不进行大量的目录移动,因为该文件夹的用途与我在互联网上阅读到的不同,也就是说,某些文件夹所代表的含义对于不同的人来说是不同的。
    现在,经过多个项目的实践,除了所有其他答案中的解释之外,在文件夹结构本身上,我强烈建议遵循 Node.js 本身的结构,可以在 https://github.com/nodejs/node 上看到。它详细介绍了所有东西,例如 linters 和其他工具,它们的文件和文件夹结构以及位置。一些文件夹中有一个 README,解释了该文件夹中包含的内容。
    从上述结构开始是好的,因为总有一天会出现新的要求,但你将有机会改进,因为它已经被 Node.js 自身遵循并维护多年。

    0

    只需从GitHub克隆存储库即可

    https://github.com/abhinavkallungal/Express-Folder-Structure

    这是一个 node.js express.js 项目的基本结构,已经设置了 MongoDB 作为数据库,hbs 作为视图引擎,还有 nodemon,因此您可以轻松地设置 node js express 项目。

    步骤1:下载或克隆存储库
    步骤2:在任何代码编辑器中打开
    步骤3:在文件夹路径上打开终端
    步骤4:在终端中运行以下命令:npm start
    步骤5:开始编码


    1
    你在哪里规定控制器和业务逻辑的管理方式? - Tajs
    很好的目录结构。 - undefined

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接