前言
卤煮在公司之初接触到的是一个微信APP应用。前端技术采用的是Backbone+zepto等小型JS类库。在项目开发之初,这类中小型的项目采用这两种库可以满足基本的需求。然而,随着迭代的更新和业务的增加,成堆的代码被覆盖到项目中去了,使得这样一种技术架构方式变得异常的臃肿,很多界面变得异常的难以维护,因此卤煮打算重构公司前端架构。
卤煮的想法是:采用异步模块的加载方式,将不同微信菜单进入的界面分成若干的模块文件,这样的好处是按照需求加载界面,而且每个界面都单独成模块,便于维护和独立开发。于是卤煮花了大概一个月的时间重构了前端。也就是从那时起以backbone的框架为基础,封装成一套配置框架。就这样,项目经过改良,变得比较容易维护,卤煮也从其中学到了若干经验,积累了一些有用的代码,最后逐步经过改进,在经过实践的考验(用此框架完成了其他两个中小项目),整理成了一套自己的小型框架出来,卤煮将之命名为SalutJs。它刚刚诞生,它并不怎么成熟,文档写得比较马虎,具体得看开发实例,卤煮都放到github上去了。卤煮用它做过三个项目,但总体感觉是比较不错的,它非常适合做这样的类似微信app中小型单页应用。本篇博文就是向诸位分享卤煮的一些经验和框架知识,希望能够帮助正在最类似web应用而不知道怎么下手的诸君一些小小的帮助。
架构思路
如卤煮之前说的那样,随着业务和界面的增加,代码回变得越来越难以维护。碰到此类问题,第一件想到的事情就是一个字“分”。但如何分呢?这个问题卤煮考虑了许久。卤煮做的微信开发,一个线上的点餐项目,它包含如下功能:点餐,会员中心,优惠,砍价,呼叫等等十几个,这些功能里面,每个功能里面进去会有相关的若干界面。可以想见,如果把所有的界面业务代码放在一个文件里面,整个项目会变得异常的臃肿最后奔溃。卤煮考虑的是将每个功能里面的若干界面的代码放到同一份js里面,这样,当用户使用其中一个功能的时候只需要加载一个js而不是十几个界面代码。当我们需要从一个功能里面的界面切换到另外一个功能模块里面的界面时,我们运用requirejs的异步加载方式,异步载入需要加载的文件。这样便解决了代码耦合和臃肿的问题了。值得一提的是我们结合界面的原则是根据业务需求来的。卤煮举个例子:在点菜功能里面有若干界面,但点菜功能不一定会需要会员卡功能界面,所以,我们在写点菜功能文件的时候,是不需要把会员卡界面业务包含进去的。
html模板
在渲染功能上,卤煮没有做何改变,沿用的是underscore的template方法渲染。由于界面的业务已经分开,那么html结构也对应的可以分开。不必要一开始就将不必要的html代码放入我们的主体文件中。卤煮加载html模板的原则是跟js有些一样的,方法则是用ajax讲html以文本的形式下载下来,然后渲染到界面中去。在require的时候,我们会去服务器拉去对应的模板文件,也就是说我们实现不同大功能之间的跳转需要请求两个文件,一个是xx.js,另外一个是xx.html。实际开发过程中,你不需要自己去调用这些文件,使用route.myNavigate方法,框架会自动帮助你去下载js和html文件:
目录结构
在使用Salut的时候需要按照既定的一些目录规则来创建文件结构。我们的项目大致分为若干目录:
construction:配置文件以入口文件
css:样式文件
fonts:字体文件
img:存放路径
js:存放所有基础架构js和业务代码以及模板文件
node:运行测试项目node文件(实际开发中请无视)
page_main.html:主题html文件
run.js: node文件,运行即可将项目跑起来
js文件夹下面又分了若干文件夹,存放了不同的js文件
base:salut的核心代码
core:backbone和zepto等底层代码
plugins:若干插件
tpl:模板文件
use:每个功能的业务代码文件
config:配置文件
map.html:需要用到的地图文件
入口:
page_main.html是整个项目的html,如果没有其他特殊的业务需求,所有的单页面都在此html中实现,不会有url的跳转。它的最外层是一层div包裹着的,作为最外层的容器。然后是用require引入的入口js的文件:
<body> <!-- 最外层容器 --> <div id="pageWindow"></div> <!-- 引入require 载入入口文件 --> <script data-main="construction/app" src="construction/require.js"></script> </body>
我们看到,只要当界面一开始加载,然后开始引入了app.js文件,在app.js中,我们会判断当前界面的地址,配置好require的默认配置,引入自定义配置,开始拉取对应的界面业务代码下来:
命名规则
Salut的命名有自己的一套规则:主要体现在文件命名上:在命名业务文件上采用大写字母开头,而在命名html文件上规则是tpl加小写字母开头的对应js业务文件。在为每个节目注册路由时,路由的名称为大写字母开头,界面名则为小写字母开头,但名称都是一样的。每次你建立一个新功能的时候,必须去config里配置这个功能模块文件的名字和里面对对应的界面名称的关系,在github的例子中你会看到。这样做的原因就是js没有读取本地文件的能力,所以你必须把其他功能文件中的界面写在配置文件里面,这样,当需要去load另外一个界面的时候,才知道我们是需要加载哪一个js。
路由规则
Salut并没有改变backbone的路由规则,它沿用了之前的hash做法,在backbone源码中,你可以看到有多种方式实现路由推动事件,他们是hash、pushstate、和定时函数。Salut的初衷也是分界面,每一个路由对应着每一个界面,在地址栏中改变hash值(#号后面那部分,对应不同界面)从而跳转不同的界面。这个卤煮在之前的博文中已经讲到过了,这里就不再提。路由的名称是和界面模块的名称有关系的,在命名规则里面我们也已经提到过了。
总结
Salut在构建类似以上提到的类似微信app的应用时非常适合,也非常简单。它对于中小型的app应用来说是比较合适的。学会规则后几乎只要简单的配置就能完成加入一个界面到项目中的工作。卤煮自己考虑后续把requirejs这样的模板加载文件替换掉(已经写完),最后把backbone底层框架也换调,把他做成一套完全自主的js框架。不过这是一条比较漫长的道路了。卤煮已经把相关的文档上传到了github上,里面有一整套demo,注释也写得比较详尽。诸君如果有兴趣,请关注一下。海纳百川,有容乃大。Saultjs作为初生的一套轻框架存在或多或少的问题,也由于他的实践经验不多,要求它不断的在实践中不断地进步完善。当然,凭借卤煮一人之力,实在微不足道,为此特将其开源,希望诸君为它添砖加瓦,使得它更加强大。或者可以提供自己的意见,也非常欢迎贡献代码。总而言之,卤煮在此并不是推广自己的框架,只是分享一下工作中总结起来的一些代码工具而已。如果你什么疑问,请发邮件到alberteinstein007@126.com或者在博客评论区留下你的意见,卤煮看到后会及时回复的。
唔。。。。。凌晨一点半写完,诸君能看到这里给个推荐吧。
遇到问题或者建议加群:461636182