首先Express是什么?了解Nodejs的同学应该都很知道,这是一个基于Nodejs的Web框架。
Fast, unopinionated, minimalist web framework for Node.js ---- 引自expressjs.com
Nodejs和Express都没有对项目结构进行约束,你可以很随意的构建应用,而不用考虑结构是否符合规范。这种无拘无束的方式很好,特别是对于小型应用,很容易上手,不用遵循各种约定。But,当应用规模越来越大时,良好的结构就很重要,特别是多人协同开发时,没有好的结构,你会感觉暗无天日。
代码组织没有固定的模式,有很多好的模式可以遵循,那么选择哪一种组织方式也是我们要面临的问题。未必是选择大家认为最好的,而是选择一个适合你的。
写了一堆废话,终于进入正文~
我们要说的这种结构是基于MVC设计模式的。
这种模式按照职责将应用的不同部分进行分离解耦,使得我们的代码更容易扩展、维护。这里我们不讨论MVC本身的优缺点,我们将精力集中在如何基于MVC模式建立良好结构的Express应用。实践证明,对于不同规模的项目和多人协同开发,这种结构都有良好的表现。
下面我们以一个示例开始,假设有这样一个应用:用户可以登录,注册,评论。接着我们建立如下的目录结构:
我们来解释看下这个结构:
controllers/– 定义路由以及相关逻辑
helpers/– 定义一些应用中公用的工具类
middlewares/– 存放Express的中间件,如可以在请求到达Controller前最一些自定义的操作
models/– 实现业务逻辑和数据访问
public/– 存放所有的静态文件,如图片,css,js等
views/– 存放表现层模板
tests/– 存放测试代码
app.js– 用于应用初始化
package.json – 记录应用信息,如版本、依赖的库等
Models
Model是用来与数据库交互的,这里除了增删改查外,也包含业务逻辑。比如,我们有一个Model叫Car,我们可以提供一个mountTyres方法,通过调用mountTyres方法来给汽车(car)安装轮胎。
你应该为每一个数据类型创建至少一个model文件,比如我们这个例子中有用户和评论model。有时,model文件变得非常大时,我们可以根据内部的业务逻辑,将它分离成多个小文件。
你应该让model独立于其他模块,它不需要知道其他model,不需要知道controller,不需要知道有哪些模块在使用它,不需要接受请求或返回响应。
这么做的目的是为了提高你的Model的可维护性。它们方便进行测试,因为它们对外界几乎没有什么依赖。对它们进行修改也不会影响其他部分。
让我们看下示例中的Model的实现,下面是评论(Comment)的Model:
Views
views目录用来存放网页模板,通常前端工程师的工作都是在这个目录进行的。
我们也可以会建立一些子目录,对应于我们创建的Controller。这样,我们把相同功能的代码组织到一起。
对于模板语言有很多选择,比较流行的如Jade和Mustache。对于模板的使用上,尽量少得在模板中处理逻辑,如果在呈现数据前需要进行一些逻辑处理,我们需要把逻辑移到Controller中。
Controllers
这个目录我们用来存放所有的路由信息。Controller需要处理请求,调用model获取数据,使用数据渲染对应的模板返回给用户。Controller控制着应用流程。
通常,应用的每个功能需要有至少一个Controller,比如,CommentController用来处理Comment相关的请求,UserController用于处理用户相关的请求。相同的Controller中的路由地址采用相同的前缀是一种很好的做法,比如:/comments/all , /comments/new
有时我们很难决定哪些代码应该放在Controller,哪些应该放在model中。这是,你要记住Controller永远不要直接访问数据库,Controller中不应该出现write,update,fetch等dao层应该提供的方法。需要访问数据,应该调用model来获取。
在controller目录我们还有一个index.js文件,它是用来读取所有controller并且定义它们的访问前缀。代码如下:
Middlewares
这个目录中我们存放Express的中间件。中间件可以看作是controller的通用代码,会做用于多个请求,可以在中间件中修改请求(request)或者修改响应(response)。
和Controller类似,中间件不应该直接访问数据库,而是调用model来访问数据源。下面是 middlewares/users.js文件,它的作用是从数据源读取用户信息,并添加到请求中:
接着,我们再定义一个认证中间件,用来判断请求中是否有user,如果没有,返回401错误:
Helpers
这个目录用来存放一些通用的工具类。
Public
存放静态文件。通常包含子目录,如images, css , js 等。
应用部署时,使用Nginx或Apache服务器来管理静态文件要好过使用Node,它们可以提供更好的性能。
Tests
这里存放所有的测试文件,可以创建子目录如: controllers, helpers , models等分别用来存放各个模块的测试文件。
写在最后
为了让大家能更快速搭建新项目,我会稍后补充一份按照这个结构搭建的基础项目供大家下载,如果你等不及了,请丧心病狂的打赏~