重构前的状态:
    大量的js代码混在繁多的Jsp文件中,对第三方的js库依赖也很杂乱。虽然在部分交互性较强的页面中,将js代码分离到了独立的js文件中,但是代码结构及依赖管理依然很乱。
不说新人来了无所适从,就是我自己看了,也会一头雾水。不是代码有多深奥,是看着实在太累。于是,一次重构工作开始了。

重构中的事情:
    1、首先,整个项目的页脚页头都有用到一些js和js库,这些具有共性的js先抽离到一个独立的head.js与foot.js中,放到include文件夹下。

2、对于公用的js库,如jquery,blockUI,jquery-template,日历控件等,先通过<script>标签依次放置于foot.jsp中。

3、对于强交互的页面,将其js文件放在include平级的目录下,以该项目名命名, 如app。

4、第一步的脚本分离工作就完成了,但这只是万里长征的第一步,接下来就需要管理好这些依赖和合理组织其中的代码结构了。

5、对于js库的管理,可以用lab.js或require.js,在本次重构中,两者都使用了。由于从jsp重分离出来的js代码没有良好的组织,其对第三方库的依赖也很难一时理清。
        再者,重构之事,有时间上的要求,只要分阶段走了。先保证js分离后能够不影响项目正常运行,然后再一步步合理优化代码。

6、于是使用了lab.js,理由是可以按原页面要求的加载顺序来加载第三方js库,这样可以确保抽离出来的js能在lab.js加载相关库后,正确的运行。
        foot.jsp中定义了全局变量

 1         <script type="text/javascript">
 2             var username = "${loginUser.username}";
 3             var version = "${version}";
 4         </script>
 5         <script type="text/javascript" src="${staticJsRoot}/common/LAB.min.js?${version}"></script>
 6         <script type="text/javascript">
 7             //供其他包含页面使用,确保在一个依赖请求链条内
 8             $LAB = $LAB.script(LOCATION.js+"/common/jquery-1.6.1.min.js?"+version).wait()//确保顺序加载
 9                               .script(LOCATION.js+"/common/include/head.js?"+version).wait()
10                              .script(LOCATION.js+"/common/include/foot.js?"+version).wait(function(){
11                                     //执行全局初始化,如异步登录检测等
12                                     loadFootReady();
13                             });
14         </script>

7、在强交互的页面,使用require.js来管理本页面所用到的js,异步加载,通过初始化函数执行各种定时器启动、事件绑定等。而初始化函数所需要的参数,
       在jsp中预初始化,供js使用。
        app.jsp中

 1

             <script type="text/javascript">

//需要用到的初始化参数
 2         var initParams = {
 3                 maps:{
 4                     aIds:[]
 5                 },
 6                 aid: '${aid}',
 7                 bid: '${bid}',
 8                 cid: '${cid}'
 9         };
10 
11         <c:forEach items="${list}" var="obj" varStatus="sta">
12             <c:choose>
13                 <c:when test="${obj.type==1}">
14                     initParams.maps.aIds.push(obj.aId);
15                 </c:when>
16             </c:choose>
17         </c:forEach>
18         
19         //使用labjs继续加载本页面需要用到的js库
20         $LAB.script(LOCATION.js+"/common/jquery.tmpl.js?"+version).wait()
21                 .script(LOCATION.js+"/common/audio/jquery.jmp3.js?"+version).wait()
22                 ;
23         </script>
24         <!--使用require.js加载这个应用的js-->
25         <script data-main="${staticJsRoot}/apps/view/main.js" src="${staticJsRoot}/common/require.js"></script>

8、接下来就是这个应用的js代码重构了,充分利用requireJs良好的模块管理机制,让代码结构更合理,维护更便利,可读性更强。
    main.js中

 1     //首先定义好要用到的全局配置
 2     requirejs.config({
 3         baseUrl : LOCATION.app,
 4         paths: {
 5             "util":            "utils/util",
 6             "jsonUtil":     "utils/jsonUtil",
 7             "domUtil":     "utils/domUtil",
 8             "eventUtil":   "utils/eventUtil",
 9             "bUtil":         "utils/bUtil",
10             "cUtil":         "utils/cUtil",
11             "dUtil":         "utils/dUtil",
12             
13             "service":     "service/service",
14             "aService":     "service/aService",
15             "bService":    "service/bService"
16         }
17     });
18 
19     //然后加载应用的各种组件,并执行函数调用,run起来
20     requirejs(["config",
21            "service",
22            "util",
23            "template",
24            "loader",
25            "public"], function(config, service, util, tmpl){
26                    window.MyApp = config;
27                    MyApp.tmpl = tmpl;
28                    //使用jsonUtil,将各种util combine成util.js,将各种service combine成service.js
29                    util.combine(MyApp, service);
30                    util.combine(MyApp, util);
31                 
32                 MyApp.ready();
33            }
34     );

9、jsonUtil代码:

 1 define(function(){
 2     return {
 3         /*
 4          * util包里的核心工具类
 5          * 将json2中的key-value添加到json1中,
 6          * 如果json2为空或未定义,则将json1添加到调用者中
 7          * @author  idu
 8          */
 9         combine: function(json1, json2){
10             if(!json2) {
11                 var temp = json1;
12                 json1 = this;
13                 json2 = temp;
14             }
15 
16             for(var i in json2){
17                 json1[i+""] = json2[i];
18             }
19 
20             return json1;
21         }
22     };
23 });
24 

小结:当然重构并不是三言两句就能说清楚了,不过这一步走过来后,现在无论前端性能,还是代码质量、管理,都有了质的提升!

简述WEB项目前端脚本的一次重构历程,labJs,requireJs实践[转载]的更多相关文章

  1. Java Web 项目打包脚本

    可用于 (但不限于) Eclipse 项目. 一次性生成:1. Java doc .zip 包:2. Java 源代码 .zip 包:3. Java 二进制文件 .jar 包:4. Java 源代码加 ...

  2. 将Ext JS 6应用程序导入Web项目

    由于Ext JS 6包含了Sencha Touch,因而在应用程序结构有了些改变,Ext JS 5的方法已经不适用于新版本了.经过研究,发现6导入Web项目要比5简单. 下面来说说导入的过程. 使用S ...

  3. 一个完整Java Web项目背后的密码

    前言 最近自己做了几个Java Web项目,有公司的商业项目,也有个人做着玩的小项目,写篇文章记录总结一下收获,列举出在做项目的整个过程中,所需要用到的技能和知识点,带给还没有真正接触过完整Java ...

  4. 做一个完整的Java Web项目需要掌握的技能[转]

    转自:http://blog.csdn.net/JasonLiuLJX/article/details/51494048 最近自己做了几个Java Web项目,有公司的商业项目,也有个人做着玩的小项目 ...

  5. 做一个完整的Java Web项目需要掌握的技能

    最近自己做了几个JavaWeb项目,有公司的商业项目,也有个人做着玩的小项目,写篇文章记录总结一下收获,列举出在做项目的整个过程中,所需要用到的技能和知识点,带给还没有真正接触过完整Java Web项 ...

  6. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

  7. 关于web项目中的图片上传、并在前端显示问题(tomcat中配置文件上传虚拟路径)

    一.数据库存储 直接把图片的二进制码存到数据库,可参考blog:http://blog.csdn.net/hope2jiang/article/details/590733 直接存图片在mysql上面 ...

  8. 【转】关于web项目中的图片上传、并在前端显示问题(tomcat中配置文件上传虚拟路径)

    一.数据库存储 直接把图片的二进制码存到数据库,可参考blog:http://blog.csdn.net/hope2jiang/article/details/590733 直接存图片在mysql上面 ...

  9. 简述泛型、用Maven创建Web项目以及在Web项目上整合SpringMVC

    表设计 Timestamp列是否取消"根据当前时间戳自动更新" 是否null及默认值选择合理不合理 外键命名规范及更新和删除时的动作是否合理   泛型 类型参数 --允许在外部指定 ...

随机推荐

  1. 上交oj1219 重要的逆序数对

    题意: https://acm.sjtu.edu.cn/OnlineJudge/problem/1219 思路: 在经典的归并排序求逆序数对算法基础上稍作修改. 实现: #include <io ...

  2. Centos5安装***

    最近shadowsocks挺火,看了几张帖子,感觉在手机上应该挺好用,电脑都是挂着ssh,用不到***了,下面贴出服务器安装过程: yum install build-essential autoco ...

  3. PMP项目管理学习笔记(8)——整个管理之监控项目工作、综合变更控制、结束项目或阶段

    监控项目工作 输入:企业环境要素.组织过程资产.项目管理计划.绩效报告 工具:专家判断 输出:变更请求.项目管理计划更新.项目文档更新 综合变更控制 输入:企业环境要素.组织过程资产.项目管理计划.变 ...

  4. 为什么ABAP整型的1转成string之后,后面会多个空格

    有同事问这个问题:lv_s是从int4转过来的,长度为2,和硬编码的lv_s2(长度为1)相比,后面多了个空格. 为什么?查SAP ABAP的编程帮助F1 help. 帮助文档说的很清楚了:如果赋值操 ...

  5. SEO 第三章

    SEO第三章 本次课目标: 1.  掌握关键词的选取方法 2.  掌握关键词的竞争强度分析 3.  掌握关键词的拓展方法 一.关键词的选取 选择关键词的时候可以根据公司网站的定位,围绕公司的主营产品或 ...

  6. JavaSE-03 Java选择结构

    学习要点 if选择结构 switch选择结构 if选择结构 单分支if选择结构 语法结构 应用场合 问题:如果王小强的Java考试成绩大于98分,小强就能获得一个iphone8作为奖励. 复杂条件下的 ...

  7. 核心动画中的几种layer

    第10章其他有用的层 免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之 ...

  8. c++_凑算式(最新方法)

    凑算式 B DEFA + --- + ------- = 10 C GHI (如果显示有问题,可以参见[图1.jpg]) 这个算式中A~I代表1~9的数字,不同的字母代表不同的数字. 比如:6+8/3 ...

  9. Django之web本质

    Django之web本质 Web的本质,是基于socket玩的. 在我们上网的过程中,一个访问请求是如何工作的. Web的框架: 网络的连接都是基于Socket 在连接中有TCP/UDP 和HTTP协 ...

  10. Python-接口自动化(十一)

    配置文件的作用(十一) (十二)配置文件 1.python当中有一个模块可以读取配置文件里面的信息:configparser,对这个模块进行导入之后就可以使用了,import configparser ...