zoukankan      html  css  js  c++  java
  • 自己写js库,怎么支持AMD

    最近我打算把之前做项目写的一些工具集成到一个js库中,但是库既要在普通环境正常运行,又要在AMD环境下不暴露全局变量。一时间挺头疼的。随即我参考了一些现在流行的库的源码。学着写了一下,感觉还不错。

    既然要支持AMD,那么我们需要选择一款AMD的模块加载器,这里我使用requireJS。

    至于库我使用的是我最近写的一个小工具库 mTools, gitHub地址:  https://github.com/grARM/mTools  。那我们开始吧。

    一、判断环境

    我要实现的效果是在一般环境暴露一个全局变量,在AMD下可作为模块加载。既然要区别对待,就要先判断出不同的环境。那么AMD环境有什么特点呢?

    使用过requireJS的盆友,一定很熟悉define(),我们就是用define()来定义一个模块的,所以我们有了第一个条件:

    typeof define === "function"

    但是仅仅因为define是个函数,是不是不够严密呢,万一我也定义了一个同名的全局函数怎么办。我们创建一个requireJS的项目,在控制台输入 define.amd  ,控制台会返回一个对象,其实他是define方法的一个属性,查了一下requireJS的官网,发现这个属性就是用来说明当前的模块加载器是AMD协议的,比如在我们的require工程中控制台输入define.cmd就会返回  undefined 也就是说我们得到了第二个判断条件:

    if ( typeof define === "function" && define.amd ){
    }

     二、分别处理

    我的工具模块,可以理解为一个函数,这个函数的最后会把需要被外界访问的部分属性return 出去。那么被return的这个对象,就是普通模块中暴露在全局的变量,同时他也是AMD中的模块返回值。换句话说,我只要根据上面的条件处理返回值(或模块函数)就实现了我们的目的。那么怎么处理呢?

    对于一般环境,我们直接将模块函数运行后端的返回值赋值给一个window下的变量就可以了。

    对于AMD环境下,刚才我们说过要用define来定义函数。所以对于这两种情况我们可以这样处理:

     1 ;(function (factory){
     2     if ( typeof define === "function" && define.amd ) {
     3 
     4         // AMD. Register as an anonymous module.
     5         define(factory);
     6     } else {
     7 
     8         // Browser globals
     9         // 以我的库为例  返回mTools
    10         window.mTools = factory();
    11     }
    12 })(function(){
    13     我们的js库
    14     return {
    15        //模块返回值
    16     }        
    17 
    18 });

    注意,我们将js库函数作为立即执行函数的参数传入我们的分析函数,即为factory(未执行),如果AMD环境,就定义为AMD模块;如果是一般环境,就直接运行将返回值赋值给   window.mTools

    随即我测试了一下,确实在一般环境暴露一个全局变量,在AMD下可作为模块加载(没有暴露全局)。

  • 相关阅读:
    MSSQL 事务说明
    创业课堂之团队
    如何开发HTML编辑器
    IE和Firefox对Documnet,iframe的处理
    jQuery控制iFrame
    如何更高效的制作可通用的HTML页面
    天下武功,无坚不破,唯快不破
    Flash本地通讯
    播放本地MP3 (二)
    播放本地MP3 (一)
  • 原文地址:https://www.cnblogs.com/webARM/p/4795589.html
Copyright © 2011-2022 走看看