zoukankan      html  css  js  c++  java
  • seajs学习笔记

          现在公司开发的项目大量用到了JS,由于项目模块要求不同,编程人员的开发水平也不同,前端的JS写的非常的乱,最近一段时间也在思索着如何才能以最小的成本,在不大幅提高编程难度的前提下最大化的规范前端编程.前几天看了一篇文章:使用SeaJS实现模块化JavaScript开发,然后又仔细研究了关天,感觉很不错,现将研究心得分享如下.

          一.模块化

          JS的模块化编程思路其实来源于一系列编程规范(如CommonJS)和此规范的一些实现(如Nodejs),虽然我对以上提到的这些东东没有什以研究,但是以我在改别人前端代码的痛苦经历和就"模块化"这三个字的字面意思来讲,还是能够理解它想表达的意思.所谓"模块化",就是以分治法为依据,把一个大的问题分解成若干个高内聚,低耦合的小的问题.最后通过一系列依赖关系明确的相互调用,最后共同解决那个大问题.这里的两个关键是高内聚与明确的低的耦合.seajs解决的正是后面一个关键.

          二.seajs概述

          大部分情况下,引入一个新的内容都会增加旧有内容的复杂性.既然它的目标是降低复杂性,那么它本身就应该保持足够的简单.seajs非常好的遵守了KISS原则.SeaJS仅向全局公开了两个标识符:seajs与define.

          seajs对象有两个方法use和config.下面是define方法的结构图

         

          可以看到,define的第一个参数与module的属性都有一个叫id的.其实他们是一回事,如果传入id,module则用它,如果不传入,则使用一个默认的规则生成每个模块的id.

          define的第二个参数dependencies与module的属性dependencies也是有关系的.module的属性dependencies是传入的dependencies集合并上使用require方法获取的依赖的集合.

          define是个重要的方法,它有三个参数:require,exports与module.这个方法的构造完全附合CommonJS下面的Modules/Wrappings规范:使用require获取“依赖”,使用exports导出“接口”,而module则代表被定义的模块本身.

          seajs对象与define方法的具体使用方法可以参考官方的文档进行学习.从一般使用顺序来讲,首先通过seajs.config进行全局配置,然后通过define定义各个模块,最后通过seajs.use方法使用各模块.如果能按照这个方法去理解,应该就能够很快的掌握这个框架.

          下面来谈谈我对使用seajs框架的理解

          一.代码组织

          如果一个网站的JS全部是由seajs组织的,你就会发现所有的js只会出现在两个地方:define里与seajs.use里.在define里,因为这里是模块定义的位置;在seajs.use里,因为这里是唯一能够使用由define定义的模块的地方.通过define定义模块,所有的功能都被封装成一个个js对象,且这些对象是闭包的,只有通过seajs.use方法的第二个参数----一个回调函数的参数才能使用这些定义的对象.

          二.顺序加载

          由于seajs仅仅是一个模块加载器而不是文件加载器,它不能保证脚本一定是按代码的书写顺序进行加载.为了应付这种情况,seajs推荐使用LABjs配合seajs进行使用.

          Labjs的使用也比较简单,使用script方法加载脚本,使用wait方法执行脚本.更加具体的说明请参照其官方文档.

          三.循环引用

          参见下面三段代码:

    //a.js
    define(function(require, exports, module) {
        var b = require("b");
        alert(b);
        return b + 1;
    })
    //b.js
    define(function(require, exports, module) {
        var a = require("a");
        alert(a);
        return a + 2;
    })
    //html
    seajs.use(["a.js"], function(result) {
        alert(result);
    })

          请问发现了什么问题.答案是a模块与b模块发生了循环引用.这个问题如果在seajs早期的版本里,貌似会报异常,但是现在不会了.当html页面请求a模块时,a模块发现其依赖于b模块,于是执行b模块.但是此时发现其又依赖a模块.seajs现在的处理是直接返回一个空对象{},所以先是弹出[object Object],然后弹出[object Object]2,最后弹出[object Object]21.

          四.脚本改写

          现有其它类库是不能直接被seajs引用的,而是需要根据SeaJS的的模块定义规则对现有库进行一个封装.以官方封装的jquery1.7.1为例:

    (function(factory) {
    
      if (typeof define === 'function') {
        define('#jquery/1.7.1/jquery', [], factory);
      }
      else {
        factory();
      }
    
    })(function(require) {
      //jquery原生代码
      if (require) return $.noConflict(true);
    });

          它的封装规则,就是在jquery原生代码的上下加上特定代码.可以看到当typeof define == 'function',则说明当前js环境为seajs环境,使用define方法进行封装,否则直接调用传入的factory匿名函数.

          对于匿名函数,如果是seajs环境,则传入的require变量不为空,则就回调用jquery的noConflict方法.该方法可以让你自定义jquery的控制变量.

          这样封装的好处理,如果没有seajs环境,则可以像普通写法一样在script标签引入脚本,如果是seajs环境,则通过seajs引入.同一个脚本满足了两个执行环境.

          五.调试模式

          seajs还提供了一个官方插件plugin-map.js,它提供了seajs的在线本地调试模式.当你把它放在seajs的同级目录下,然后在URL后面加上?seajs-debug参数时,窗口的右下脚就会出现一个输入框让你输入需要调试的脚本的路径.点击刷新后,网站脚本的来源就变成你设定的来源了.

          以上就是我研究seajs的心得.在研究的过程中参考了作者的官方参考与园友的研究成果,在这里一并感谢了.也祝愿玉伯这个少有的得到众多认可的国产框架写的越来越好:)

          参考的文章

          1.从 RequireJS 到 SeaJS (1), (2), (3), (4), (5) (可能需要FQ)

          2.在线本地调试大观 (可能需要FQ)

          3.jQuery 插件的模块化 (可能需要FQ)

          4.seajs官方

          5.拥抱模块化的JavaScript

          6.什么是CommonJS

          7.使用SeaJS实现模块化JavaScript开发

          8.SeaJS快速入门,让js代码模块化 - 2011-09-09修订,新增参考资料

          9.JavaScript模块化开发库之SeaJS

          10.seajs – 全局map,调试利器

          11.对之前分享到微博demo的一些改进

          12.关于seajs模块间相互依赖调用的解耦问题

          13.Javascript文件加载:LABjs和RequireJS

          14.labJS 介绍

          15.LABjs

          16.我的模块加载系统 v3

          17.工程化前端开发

          18.js模块化开发---js大项目代码组织和多人协作的解决之道

          19.通用前端开发框架(一)

  • 相关阅读:
    CodeForces 659F Polycarp and Hay
    CodeForces 713C Sonya and Problem Wihtout a Legend
    CodeForces 712D Memory and Scores
    CodeForces 689E Mike and Geometry Problem
    CodeForces 675D Tree Construction
    CodeForces 671A Recycling Bottles
    CodeForces 667C Reberland Linguistics
    CodeForces 672D Robin Hood
    CodeForces 675E Trains and Statistic
    CodeForces 676D Theseus and labyrinth
  • 原文地址:https://www.cnblogs.com/ljzforever/p/2490932.html
Copyright © 2011-2022 走看看