前几天刚刚把项目的组织结构进行了一次重构,这是前端项目至今第二次进行组织结构上大的变化,也是一个"folder by type"到"folder by feature"的过程.
为什么有这个过程?
因为感觉到项目的日益庞大,每次修改一个地方我可能要打开三四个文件,比如说一个页面上的哪里要修改.那么首先是页面的HTML,然后是Controller,Less,对应接口的service文件等等.整个项目是我一手构建的可能还不会出问题,只是找的时候要回想一下对应的文件,但是如果一个新的成员加入进来,不免就有些疏漏,因为他也很难确定一个页面上的局部变动,到底要涉及到哪些文件.
最开始在项目刚刚构建的时候,也就是只有一个页面的,就开始按照文件类型进行项目的组织.不过随着项目的庞大,以及各方面其他的影响,逐渐,按照type进行划分已经出现了职责不清晰的感觉.
最开始项目的结构大概是这样,太具体的有点记不清了,大概是这样的:
- -- static
- -- js
- -- app.js
- -- routers.js
- -- services.js
- -- directive.js
- -- filter.js
- -- controllers
- -- userController.js
- -- someModule.js
- -- less
- -- index.less
- -- user.less
- -- someModule.less
- -- build
- -- all.2014090901.js
- -- all.2014090901.css
- -- templtes
- -- index.html
- -- user.html
基本结构就是按照功能对Controller进行划分了,因为做的Angular SPA所以基本上一个Controller对应一个子页面,然后将所有的js以及less合并压缩出来,在index页面加载.当然其实还做了一些更细致的工作,这里只是说一下项目的雏形.
接下来都做了哪些改变?
与其说接下来做了哪些改变,不如说一下有哪些东西促进了我们要进行改变.说到这在岔开一个话题,什么叫做稳定良好的文件组织结构,一个我现在下的定义就是"健壮并包容".当一个东西发生变化的时候,你当前的组织结构能够以很小的代价去适应新的变化,而不是整个项目大改特改,甚至牵连到代码.
当雏形完成后,项目日益增大,有两个task进入了要考虑的流程.一个是关于项目的自动化构建,包括是库文件的管理,库之间的依赖关系,代码的压缩合并等,还有静态资源的版本号,开发模式和发布模式下不同代码构建等等.另一个问题就是URL的设计,怎么和文件的组织结构保持高度统一.
这两个问题都比较杂,先说URL的设计吧.
关于"好的URL设计"的定义有好几条,可以自行百度,我不打算抄袭百度百科了.只谈我认为最重要的就是对用户的友好,什么叫URL对用户的友好呢?说白了就是让你的URL一看就懂,一猜一个准.我认为这样设计就可以了,可能你会说了谁会无聊到去记住URL地址呢,想要以后访问收藏一下就可以了.
这个我没什么兴趣去反驳,不过你怎么看不见百度或者淘宝的网站将地址设计为"www.baidu.com/hsakudhkajshdgjasgdjhsgfjhsagfjhsdgfjhasgfj786347823yuisbhdufy".
URL的语义化很大程度上表达了对用户的友好.比如我现在"/restaurant","/restaurant/new","/restaurant/2","/restaurant/2/edit"这几个URL对应的页面分别是:
餐厅页面(列表数据),新建餐厅页面,餐厅id为2的餐厅页面,餐厅id为2的餐厅编辑页面.
很容易猜到不是吗,将2改为其他对应的id也能访问到指定的餐厅页面.这个URL映射关系从结构上说就应该与我们的文件夹结构对应,也就是应该有一个restaurant文件夹,然后里面有详情,新建,编辑等页面以及对应的其他文件.所以基于良好的URL设计,我们是需要一个符合语义的组织文件结构的.
项目的自动化构建怎么牵扯到文件结构?
每个小话题感觉都能引出一些详细的深入的东西,项目自动化构建为了解决什么问题?这个解决了很多问题,但是对于一个Angular SPA来讲主要有两个需求.一个是将静态资源合的整合,比如合并压缩,发布时使用带有版本号的静态资源.另一个是开发过程中的一些Less文件以及JS文件的重新编译,页面自动刷新等.
简单说一是为了发布,一是为了开发,为这两个步骤更加便捷有序做出一些努力.
在上面的过程中,不管是开发还是发布,都会生成很多build出来的文件,这也会影响到你对项目目录和文件组织的调整.
新构建好的项目结构
每一次对于项目的修改都涉及到方方面面的东西,很繁杂,随着项目的日益庞大,这种修改的成本也会越来越高,所以及早确定一个好的架构是很迫切的.先给出当期啊的结构:
大致说一下现在怎么划分的,因为是SPA所以肯定有一个index.html作为页面的承载,app.js是angular的main文件,app.less是所有Less文件的入口.
components是angular的各个组件,包括common,services,directives,filters,router,run.js(这个主要是放置一些需要随App一起启动运行的代码,例如插件初始化配置,以及类似路由监听处理事件等).
一个子页面按照功能模块划分在modules中,对应的Controller的JS文件,Less的CSS文件都在一个文件夹内.
build目中的内容全部是生成的,我使用了Bower和Gulp搭配使用,自动化构建项目.
这样目录结构就清晰了,公共的部分被单独划在一起,每个页面对应的相关文件被组织在一起,然后按照功能安排进行划分.这样在维护的时候就能很容易找到要修改的相关文件.同事日常开发和项目发布都是用build中的文件,里面有两套不同的文件对应开发和发布。
这样感觉整个项目都清爽多了.
项目构建之路岂止于此
因为篇幅所限很多东西还是没法一起交代清楚,比如Controller的职责划分,services的结构,以及Bower和Gulp如何配合进行完整的项目构建.这些过后可能会在Github上留一套架子,有兴趣的可以留言。
虽然感觉很多东西没说明白,不过关于组织结构的事儿,大概也就是这些了.只是项目的构建之路漫漫而修远,***还有点心得和大家分享一下。
项目的构建做到现在只能说完成了初级的一步,如果稍微好点说,算是中级吧.那么理所应当该有个高级或者说***目标.angular是一套框架而不是库,这就给了我们很多发挥的空间,从现在的情况来看,还有那些不足需要改进的东西,我总结了一些点,当然这些点对大多数项目可用:
各部分之间的耦合度,是否做到深度解耦。
Controller的职责是不是过大,不单单是业务,很多乱七八糟的东西都丢到Controller中,导致形成了'super controller'。
一些公共的东西是不是没有抽取出来,还在重复copy代码。
MVVC的概念,是不是发觉自己在angular中没有M的概念。
用面向对象的思想看看架构和代码,有没有做到职责单一,开放闭合.
其实还有很多东西需要改进,我也一直在慢慢组织.可以说,一套搭的比较完善的架子有两个最为突出的特性.其一就是结构清晰维护方便,因为每个部分职责单一,对修改闭合,对扩这开发.另一个特性就是开发效率极高,大量的内容被抽象出来,做成公共的组件,70%的代码已经被写完了,只要写业务那部分即可。
如果说还有一个很重要的原因去让我们孜孜不倦的完善架构,就是为了不在项目日益庞大的时候无法有效的维护,个人感觉这是最主要的一点,就是通过清晰的代码和结构,降低维护的成本。