资讯专栏INFORMATION COLUMN

seajs模块化改造实践

justjavac / 3325人阅读

摘要:为对象字符串时,表示模块的接口就是该对象字符串。我们来看一个实际的例子支付宝的登陆页面。在网页支付宝收银台中的运用很直观的就能看到插模块的合并,这个合并的工作就是构建工具的功劳了。

前言

一月份的时候,临近放假,拿到一个需求,新增一个产品,我一个前端对一个java后端,两个星期的开发时间。 因为大部分功能在别的产品都已经有了,基本都是简单处理一下拿过来,再添加一下额外需要的功能,比如选择出行国家等。前一天拿到文档看了下,搞清楚之后,第二天开工,基本一天就把功能做完了。这一天的大部分时间还是花在-找代码上。无他,实在是遗留的代码 不是很清晰。

因为系统比较旧,前后端也没有分离,jsp的,代码也很混乱,逻辑里面还有很多奇怪的注释,在这些上面做了很多无用功。 基本做好功能,联调测试,通过之后基本就OK了。

但是两个周的时间才用了两三天。还有十来天呢,怎么办呢,看着这些混乱的代码,本着造福别人,也为以后的方便,就想着,用模块重新组织一下吧。因为去年有过这方面经验,轻车熟路。所以,就有了后来的故事和今天的这篇文字。

改造前

改造前的代码大概是这个样子的:

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        


        
            
            
            
            
            
            特别约定
             
            
            
            
            
标准保费 元/人
优惠价 元/人

不多贴代码了,大概就是这个样子的。这种情况的原因大概是:

1.起初的页面是后端人员写的,没有很好的组织各种资源。写到一定数量之后,各种逻辑已经耦合在一起,别的人接手之后,又不敢乱改,就按以前的做法复制粘贴,做好自己的那一块。久而久之,页面就越来越复杂,冗余也越来越多,形成了一个恶性循环。

2.网络环境不允许。使用公司标配的联想笔记本,标装之后,收到公司安全策略的限制,很多技术网站无法访问,查资料有时候只能看百度快照,有些同事只好用手机或者自带电脑来解决这个问题。至于 github,google,基本是不可能的。

3.没有代码规范。基本每个人都是按照自己的风格来,最后归并之后的代码就显得很混乱。

由于不能使用脚手架自动化工具,这种情景要做模块化,requireJs/seaJs 是比较好的选择。去年用过requireJs,这次就用一下seaJs.

由于项目中的样式文件实在太多太杂,时间上不允许我重新组织一遍,所以就只对逻辑代码做了模块化处理。

组织模块

要组织模块,首先要弄清楚相应的规则。最好的方式当然是看 seajs文档 了.

这里也简单介绍下几个常用的功能。

    
    // 页面中包括的js
    
    

    
    

    

再看一下配置信息:

    seajs.config({
    base:"./js/",
    paths: { //当目录比较深,或需要跨目录调用模块时,可以使用 paths 来简化书写。 
           "seajs": "seajs/2.3.0/sea.js"
    },
    alias:{ // 设置别名,方便调用 , 当模块标识很长时,可以使用 alias 来简化。
        "jquery" : "lib/jquery/1.10.0/jquery.min.js",
        "Hello":"mod/mod4.js",
    },
    map: [
        [".js",".js?1.0"]
    ],
    debug:true //值为 true 时,加载器不会删除动态插入的 script 标签。插件也可以根据 debug 配置,来决策 log 等信息的输出。
});

然后是页面入口:

//main.js

/*
    define define(factory)

    define 接受 factory 参数,factory 可以是一个函数,也可以是一个对象或字符串。

    factory 为对象、字符串时,表示模块的接口就是该对象、字符串。比如可以如下定义一个 JSON 数据模块:

    define({ "foo": "bar" });
    也可以通过字符串定义模板模块:

    define("I am a template. My name is {{name}}.");
    factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module:

    define(function(require, exports, module) {

      // 模块代码

    });
*/
define(function (require, exports, module) {

    var $ = require("jquery");
    
    console.log($); 
            
    require("mod1");
    
    var Hello = require("Hello");
    
        Hello.init();
        
        
    // other code...
        
});

看一下模块内的代码:

//mod1.js
    define(function (require, exports, module) {
        console.log("mod1加载完毕");
});
//mod4.js
define("Hello",function(require,exports, module) {

    var Hello = {
            sayHello:function(){
                console.log("hello");
            }  
    }

    module.exports = Hello;
});

打开页面控制台,就会看到输出的信息:

说明我们的模块已经被成功的被加载了。

当然 实际的工作中还要用到各种插件,这就需要知道如何改造现有文件为 CMD 模块

这些在文档中都能找到。

以上简单介绍了使用seajs 组织模块的方法。

当然,模块写完之后呢,我们还需要相应的构建工具。

玉伯说:

如果使用 Sea.js,强烈推荐采用配套的构建工具来压缩、合并代码。如果不这么做,可能会带来不少额外的工作甚至隐患。

如果不合并代码,也能运行,你会看到你的插件代码都会以async的方式插入到页面的头部。而且需要你手动处理依赖关系,也产生了额外的请求,不是很友好。如下图:

所以,为了避免意外的发生,也为了减少请求数,应该合并模块。

我们来看一个实际的例子-支付宝的登陆页面。

在网页支付宝收银台中的运用

![clipboard.png]

很直观的就能看到插模块的合并,这个合并的工作就是构建工具的功劳了。

我们也来实现一下。

先看效果吧,执行模块合并之后,入口文件可以是这样的:

这样就实现了模块的打包合并。

我这里使用了gulp来实现这一步, 代码如下:

//seajs合并模式
gulp.task("seajs", function () {
    return merge(
        gulp.src(src + "/js/!(lib)/**/*.js", {base: src + "/js"})
            .pipe(transport())
            .pipe(concat({
                base: src + "/js"
            }))
            .pipe(replace({
                patterns: replace_patterns
            }))
            .pipe(gulp.dest(dist + "/js")),

        gulp.src([src + "/js/lib/**/*.js", src + "/js/common.js"], {
                base: src + "/js"
            })
            .pipe(replace({
                patterns: replace_patterns
            }))
            .pipe(gulp.dest(dist + "/js"))
    );
});

使用gulp提取模块有其他更详细的教程,这里提供一个我认为比较好的:

介绍一种基于gulp对seajs的模块做合并压缩的方式

那个支付宝的登陆页 这里给出完整代码,给大家观摩:







支付宝快捷收银台




















    
加载中...

登录支付宝

返回
忘记密码
mobileclientgw-30-5
改造后

改造到最后呢,页面逻辑清爽多了,再有新的模块,写好之后别人直接调用就可以了,write once, run everywhere .

define(function(require) {

    var $ = require("jquery"),
        $body = $(document.body),
        setDate = require("components/setDate"),
        selectCity = require("components/selectCity"),
        commonTools = require("tools/commonTools"),
        FastClick = require("fastClick"),
        myLayer = require("myLayer");


    //内部统计
    var webTrends = require("webTrends");
    webTrends.init();

    // 百度统计
    var baiduTrends = require("baiduTrends");
    baiduTrends.init();

    // 初始化时间选择
    setDate.dateTime.init();
    
    //  选择目的地
    selectCity.init();

    var actionList = {

      "applyInsurance" :function(){
          //xxx
      }
  });    

完整的代码就不展示了,都是一些逻辑,没什么好看的。

最后

花了大概一个周的时间初步重构了一下项目代码,改得很粗糙,只是做了一些大概的拆分,毕竟遗留的代码太多,需要和小伙伴一起做这个事。

由于公司标装的电脑用不了npm那些,最后的一步是我在mac上弄好,然后拷贝到公司电脑上,中间还出了很多问题,不过好在能跑了,至于最后能不能用起来..只能说,努力吧。

seajs 可以说是上个年代的产物了,不过在一些老旧项目中,依然可以发挥光和热。

写到这里差不多也要结束了,我呢,也算完成了给自己定的一个小目标,不算多大的贡献,只当给自己一个交代。

以上大概就是全部内容,希望给大家带来一些启发和帮助,谢谢。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81546.html

相关文章

  • 前端seajs块化实践

    摘要:前端模块化开发的价值恼人的命名冲突烦琐的文件依赖使用来解决除了解决命名冲突和依赖管理,使用进行模块化开发还可以带来很多好处模块的版本管理。模块化可以让每个文件的职责单一,非常有利于代码的维护。模块定义规范与的模块规范非常相近。 前端模块化开发的价值1、恼人的命名冲突2、烦琐的文件依赖使用 Sea.js 来解决除了解决命名冲突和依赖管理,使用 Sea.js 进行模块化开发还可以带来很多好...

    SHERlocked93 评论0 收藏0
  • Javascript模块全揽

    摘要:要求模块编写必须在真正的代码之外套上一层规定的代码包装,样子看起来是这样的模块代码通过传递一个签名为的回调函数给函数,就可以把需要注入的变量和函数注入到模块代码内。 之前写的文章急速Js全栈教程得到了不错的阅读量,霸屏掘金头条3天,点赞过千,阅读近万,甚至还有人在评论区打广告,可见也是一个小小的生态了;)。看来和JS全栈有关的内容,还是有人颇有兴趣的。 showImg(https://...

    lily_wang 评论0 收藏0
  • seajs 源码解读

    摘要:本文主要简单地解读一下的源码和模块化原理。其中,是这次源码解读的核心,但我也会顺带介绍一下其他文件的作用的。对代码比较简单,其实就是声明一下全局的命名空间。然而,真正的核心在于处理模块依赖的问题。 seajs 简单介绍 seajs是前端应用模块化开发的一种很好的解决方案。对于多人协作开发的、复杂庞大的前端项目尤其有用。简单的介绍不多说,大家可以到seajs的官网seajs.org参看...

    LiangJ 评论0 收藏0
  • commonjs、AMD、CMD规范(相关文章)

    摘要:是对的规范的实现,当然和规范还是有点误差的。,就是遵循他提出的规范。 1:Javascript模块化编程(三):require.js的用法 http://www.ruanyifeng.com/blo...2:RequireJS 模块的定义与加载 http://www.cnblogs.com/bzggoo...(加载的顺序不定,但依赖的顺序最终是正确的;因为无需创建全局变量,甚至可以做到...

    lcodecorex 评论0 收藏0
  • 切图崽的自我修养-使用块化JS

    摘要:之前的闭包也好,自执行函数也好,都是模块化的一些尝试,直到规范推出之后,模块化才真正迅猛发展起来。因为有了模块化的概念,才有了按需加载的概念。 前言 我们来玩乐高积木吧 模块化Js已经成为了老生常谈,不过在JavaScript设计之初,由于定位的问题并没有提供类的功能,开发者需要模拟出类似的功能,来隔离、组织复杂的JavaScript代码。之前的闭包也好,自执行函数也好,都是模块化的一...

    littleGrow 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<