前言

自己学习node也有些时日了。终于在前些日子,自己的第一个node项目终于上线跑了,也第一次在node方面赚到了外快的甜头。项目是一个企业内部的oa系统,不大。抽离表面看本质,就是一个express框架下的链接mongodb展示数据并可对数据进行CRUD操作的应用。代码和demo,会在之后抽离掉一些具体业务内容后放出。下面来杂谈一些总结,不足,和随想。

1,关于配置文件

私认为配置文件存放着两种类型的信息:项目运行的环境信息关于项目结构的信息。前者保证了项目需要在另一个(地理/运行)环境跑的时候可以迅速方便地迁移,后者保证项目结构的统一性,存就在这里存,改就在这里改,以点辐射面,其他的controller,service神马的要东西都来这里取,保证了项目的伸缩性。说俗话就是“这些那些都可以根据要求自己来配”。由于小项目的代码一开始是从小伙伴那接手来的,一开始并没有专门的存放各类配置文件的地方,每个业务点里的信息都是写死的,导致一个业务信息的小修改,往往就变成代码十几处的大改动,想改个mongodb配置找半天。幸好悬崖勒马,回头是岸,岸就是/conifg/xxConfig.js。。。

2,关于视图模板

其实还是一个伸缩性的问题,对于要做若干个大体类似细节略有不同的页面,可能大家和我的第一反应都是先做第一个页面,然后复制黏贴几份,把细节改一下,OK收工。的确,这样做可能在短时间内是最快完成任务的选择。自己的小项目当时由于第一阶段要立刻有一个展示demo,时间略紧,采取的就是这个做法:几个项目管理页面,先写好一个,复制黏贴,改改细节,轻松愉快。但是当后续需要再往里添加功能时,恍然一悟,这真是给自己挖得够大,一处实现,处处黏贴,处处修改,处处可能遗漏了某个修改,出小差错的可能随着规模的增加线性增长,大修改更是苦不堪言,又闻到了上文中那种业务结构没有设配置文件时的熟悉又恶心的味道,但又覆水难收,只得把坑继续堆叠。痛定思痛,在今后写视图模板时,一定要将视图模板尽量组件化,公用的组件公用,各页面略有不同的地方也写成组件分开存放,这样修改才能有效率和集中。自己有时会疑惑,为什么一个有经验的程序员总能又快速又正确的完成任务呢?可能就是因为他对业务对视图对各种需求的抽象能力吧。合理的抽象便意味着更少的代码量,同时也意味更低的出低级差错概率,真是有点鱼和熊掌兼得的味道。。吾将继续锻炼和求索。。

3,关于各种轮子

node的迅猛发展,离开不了npm的百花齐放和神一样的用户体验,迄今为止,npm上Top100的库也是聆郎满目,几乎涵盖了开发需求的方方面面,自己总会纠结于在项目里到底用它们呢,还是不用呢?用的话,总觉得小小需求有点“杀鸡用牛刀”,不用的话,又在做稍微有点复杂的功能时有种重复造轮子的不爽感。对于这个纠结,自己现在的态度就是这些Top100库只要能用到就用。因为我们总是很难预知项目的发展,现在的简单逻辑不代表以后还是只用这些逻辑。npm这么方便,反正用了也不麻烦嘛,如果以后要用库,现在这些实现类似逻辑的代码该如何是好?比如自己在项目里做一些fs操作时,尽管知道有fs-extra这样的好轮子,但是想想简单逻辑就自己写吧,但随着项目的发展,一会需要写个mkdir -p,一会需要写个rm -rf。为了悬崖勒马,果断用上fs-extra,以至于留下一堆原生fs操作代码与fs-extra操作代码共存,看上去极其不和谐。。

4,关于缓存

知道它的魔力,但是项目对数据的实时性要求较强,并且使用规模较小,想不到好的缓存切入点(除了静态资源)。。感觉加缓存是在徒增额外的复杂,有点吃力不讨好。。

5,关于mongoose的virtual type

以前总纠结于virtual type何时用?现在的感觉是,只要这个数据是可以用现有数据库里的数据简单算出来的,就用vurtual type

6,关于mongodb(v2.6)

在初学node时,总会在各种地方看到mongodb已是node的缺省数据库,标配之类的话。的确,json文档模型,js操作语言看起来与node如此天造地设。但是随着时间的流逝,项目的深入,自己越来越有一个奇怪的感觉,mongodb真是node不可质疑的真命天子的吗?尤其是在写传统的CRUD应用时。众所周知,mongodb数据操作的原子性仅在单个document层面,并没有传统SQL的那些封装事务roll back这类的功能,直接写多document的数据改写操作,其中的一步报错了,可能就要承担数据不一致的风险。当然解决方法也有如“执行两个阶段的提交”,但总是透着一股hack味。或许,传统的SQL才更适合这类数据结构固定,并且大量依赖“事务”的应用吧?总感觉这会比mongodb省心省力不少。mongodb可能更适合那些数据以结构灵活多变独立性强几乎相互不耦合为特色的应用。所以是不是该以应用的数据模型特点来选择自己的真命天子数据库,而不是语言。。?

7,关于代码的职责分离

现在的结构:

  • controllers:路由,获取请求的内容,调用service,将service的结果返回
  • models
    • schemas/models:mongoose数据schemas和models及相关方法
    • services: 业务逻辑(包括调用mongoose与数据库进行交互)
  • views :ejs模板

起初接手时各部分比较耦合,后自己重构成此结构,用起来感觉还不错。也看了不少node项目源码的代码职责规划,感觉也大同小异了。可能会再抽象出一个工具函数目录和一个公共中间件目录,想了想的确是个可以继续改进的地方。

8,关于单元测试

项目的痛,规模一大之后跑起来,没有测试简直就是秉烛夜行。由于是半途接手并且有段时间挺赶,虽然自己感觉写的代码的功能单一性保持得不错,也挺利于写单元测试的,但是终究还是没写。靠大量的手工测试总还是不放心,心慌慌。唉,以后不管写代码或者工具,都要附上测试,并且保证竟可能高的覆盖率!(已保持。。)

最后

demo地址

1
2
3
用户名:admin
密码:admin
//请勿修改此用户的密码,或在用户管理页中删除此用户

代码