nodejs 实践:express 最佳实践 (一)
express 最佳实践 (一)
第二篇: express 最佳实践(二):中间件
最近,一直在使用 nodejs 做项目,对 nodejs 开发可以说深有体会。
先说说 nodejs 在业务中的脚色,, 在 web同构
方面, nodejs 的优势相对于其他语言来说,可以说非常巨大,基本上算是只有 nodejs 能做,其他语言根本不能做。在传统 web 开发
方面,nodejs(必竟时间太短了)的相对于其他语言来说的劣势,已经不是太明显了。
再来说说自己,算了算差不多做了 5 个项目,都是使用 express 做为项目的基础框架,然后再上面进行业务开发工作,一个路由下来,平均 10 个左右的中间件,执行效率都是不错的,开发效率也非常好,是时候总结一下 express 实践经验,同时结合配套自己的想法,来看看理想中 express 项目应该是怎样的规划,以及我是怎么想的。
思想
做一个项目的规划,首先要为项目订一个基调,就是项目架构是应该怎样设计,怎样考虑的,对业务开发是否方便,部署是否方便等要素。
我现在认为一个项目最重要的规划是:核心+插件式开发
。一个项目一定要支持这两点,如果不支持这个项目就很难做下去,为什么我这样说。因为现在的任何一个项目都不可能是一个人开发,一定是多人分工开发,如果你的项目支持 核心+插件式开发
,你就可以把核心的基础功能如:网络,日志,基础布局等功能,找个高级工程师来完成;业务开发,就可以分给一些初级工程师,并行完成,同时在做项目的时候对代码码进行审查,及时调整坏代码。这样项目,能保证进度,也能保证项目质量,不会大烂,同时人力也得到了充分利用。
这种思想落实到架构上,就是从项目的文件组织结构上考虑怎样达到这样的目标。
我是这样规划文件目录的:
按业务特性而不按分层进行规划
分层最典型的代表就是ruby on rails
,app 目录下,就是 controllers, models等目录,当然我不是说,这种规划不好,只是到项目大到一定程度,你想找某个 controller 下的一个方法,就会很麻烦,不知道没有这种体验,在几十个文件中找某个方法是怎样的感觉,搜索也是全文搜索,不能限定到某个目录下面。因此在这个项目规划中,以业务特征为插件名,在 express 中,也就是 subExpress,如果,我有一个购物车的业务,那于购物车相关的所有的项目都规在 passport
这个子应用下了,这样相关的业务在一起,方便查找,同时也方便理解和修改。当然这种规划方式也有不方便的地方,如果想跨 subApplication 调用方法,就没有那么方便。
边界显式说明
这个跟传统的 controller, service , model 没有什么区别。还是刚才的 passport 应用,按分层进行划分,包括 controllers, services, models, views, index.js, router.js。需要说明一下,在项目中我们一再强调, controllers 中负责与 http 的连接工作,只做简单参数的验证,传参和调起 services ,禁止把 rep, res 对像做为参数传递到 services 层;services 层纯业务,没有与 http 相关的任何东西,需要数据请调用 models 中的方法;models 只于数据打交到,其它都不管。这样做的好处是什么呢? 想想看,如果相把一个页面的数据拿出来做接口,只需要简单几行就搞定了,还有如果要把框架改成 koa ,你的业务都不用重写,还有你想增加 websocket 的支持,直接在 controllers 进行调整就行了。 models的作用更明显,原来的项目是一个普通是 web 项目,models 是连接数据库的,现在技术升级要前后端分离,不用数据库了,改成调用后端的接口了,你就只用把 models 用接口实现一遍,其他不用变了。 controllers 和 models 就是你业务的边界,service 则是你业务的核心,边界实现的改变不应该影响你业务。
落实
思想利用 express 的中间件思想,达到我的架构意图,如下图所示:
图中,蓝色的部分代表业务中间件,橙黄色代表 核心中间件。在一个网站项目中核心中间件,应该包括 limiter 限流操作,这个中间件主要是防止爬虫;htaccess 改写 url,这个中间件主要用,改写网站url, 为什么要改呢?因为一但网站线上运行时,路由的规则不应发生变化,但是有时候 seo 的时候,你需要兼容新老 url 的时候,这个中间件就会非常有用,网站的业务都不用变,只用在新url 到达时,变成老的再进行处理就行了;dispatch 不是一个中间件,它的思想是用来整合各个业务线的 subApplication 和主 application 的关系的;auth 鉴权,有些页面和接口需要有用户登录,如果没有用户登录,就需要跳转到登录页面,登录完成后跳回来;clientError 和 serverError 是对错误进行统一的处理,统一显示 404 , 如果是接口的话也会统一 404 的返回码。
业务端在开发时只需要在 dispatch 的地方加入自已的模块,然后就可以开始写自己的业务,不用但心自己的文件被别人改动。
下面是项目的文件夹规划:
简单说明下:
apps 目录下就写各自的业务逻辑,用 dispatch 把 主app 与 业务 连接起来,实现起来也挺简单的:
module.exports = (app) => {
app.use('/passport', require('./apps/passport'));
}
还有 shared 的存在,是为了解决前后端模板公用的问题。
与业务没有关系的代码可以,移到到 modules 中使用。
如果个业务的之间需要共享部分代码,就放到 utils 中,这个文件夹就是用来干这种事的。
总结
这个项目中规划就是,怎样使用 express 最好,另外再加上自己的一些思考,现在项目的结构出来了,后面会再讨论一些有关中间件的处理方法。
该项目的 github
nodejs 实践:express 最佳实践 (一)的更多相关文章
- nodejs 实践:express 最佳实践(四) express-session 解析
nodejs 实践:express 最佳实践(四) express-session 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs ...
- nodejs 实践:express 最佳实践系列
nodejs 实践:express 最佳实践系列 nodejs 实践:express 最佳实践(一) 项目结构 nodejs 实践:express 最佳实践(二) 中间件 nodejs 实践:expr ...
- nodejs 实践:express 最佳实践 (一) 项目结构
express 最佳实践 (一) 第二篇: express 最佳实践(二):中间件 最近,一直在使用 nodejs 做项目,对 nodejs 开发可以说深有体会. 先说说 nodejs 在业务中的脚色 ...
- nodejs 实践:express 最佳实践(三) express 解析
nodejs 实践:express 最佳实践(三) express 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固, ...
- nodejs 实践:express 最佳实践(五) connect解析
nodejs 实践:express 最佳实践(五) connect解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需 ...
- nodejs 实践:express 最佳实践(六) express 自省获得所有的路由
nodejs 实践:express 最佳实践(六) express 自省获得所有的路由 某些情况下,你需要知道你的应用有多少路由,这在 express 中没有方法可以.因此我这边曲线了一下,做成了一个 ...
- nodejs 实践:express 最佳实践(七) 改造模块 connect2 解析
nodejs 实践:express 最佳实践(七) 改造模块 connect2 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的 ...
- nodejs 实践:express 最佳实践(八) egg.js 框架的优缺点
nodejs 实践:express 最佳实践(八) egg.js 框架的优缺点 优点 所有的 web开发的点都考虑到了 agent 很有特色 文件夹规划到位 扩展能力优秀 缺点 最大的问题在于: 使用 ...
- nodejs 实践:express 最佳实践(二) 中间件
express 最佳实践(二):中间件 第一篇 express 最佳实践(一):项目结构 express 中最重要的就是中间件了,可以说中间件组成了express,中间件就是 express 的核心. ...
随机推荐
- mxnet:结合R与GPU加速深度学习(转)
近年来,深度学习可谓是机器学习方向的明星概念,不同的模型分别在图像处理与自然语言处理等任务中取得了前所未有的好成绩.在实际的应用中,大家除了关心模型的准确度,还常常希望能比较快速地完成模型的训练.一个 ...
- <bits/stdc++.h>头文件介绍(包含源代码)
注:转自http://blog.csdn.net/charles_dong2/article/details/56909347,同为本人写的,有部分修改. 之前在一个小OJ上刷题时发现有人是这么写的: ...
- 泛型(java菜鸟的课堂笔记)
1. 泛型的简单运 用和意义 2. 泛型的上限与下限 3. 泛型和 子类继承的限制 4. 泛型类和泛型 方法 5. 泛型嵌套和泛型擦除 ...
- 简化布隆过滤器——BitMap
简化布隆过滤器--BitMap 前言 前段开发项目试就发现,一部分的代码实现存在着一些性能上的隐患.但当时忙于赶进度和由于卡发中的不稳定因素,想了许多解决方案也没有机会实施.最近,正好趁个机会进行一系 ...
- sublime text 快捷收集
1. 文件快速导航: 这是sublime上面很好用的功能之一,ctrl+p可以调出窗口,菜单上的解释是gotoanythings ,确实如其所言,调出窗口后,直接输入关键字,可以在已打开的项目文件夹中 ...
- Java对象的内存布局
对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: ...
- [Leetcode] Binary search -- 475. Heaters
Winter is coming! Your first job during the contest is to design a standard heater with fixed warm r ...
- thphp5.0学习笔记(一)
1.目录结构: 其中thinkphp子目录是框架核心目录 thinkphp结构: 2.入口文件 默认自带的入口文件位于public/index.php 应用目录为application,其结构: in ...
- js获取页面宽高
网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...
- Java 并发 – 线程安全?
线程安全的定义常常让人迷惑,搜索引擎会发现无数定义,比如: 多个线程同时执行也能正确工作就是线程安全的代码 多个线程同时执行能以正确的方式操纵共享数据就是线程安全的代码. 而且还有很多类似的定义 你是 ...