最近我打算把之前做项目写的一些工具集成到一个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来定义函数。所以对于这两种情况我们可以这样处理:

 ;(function (factory){
if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module.
define(factory);
} else { // Browser globals
// 以我的库为例 返回mTools
window.mTools = factory();
}
})(function(){
我们的js库
return {
//模块返回值
} });

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

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

自己写js库,怎么支持AMD的更多相关文章

  1. 近期写js库中遇到的一个判别的问题

    最近在写一个自己的js库,正写到数组包,在里面定义了一个排序,只对纯数字数据进行排序的方法,但是在测试的时候发现一个很诡异的问题,那就是传入一个对象的时候,它没有返回erroemsg而是返回了对象,上 ...

  2. 如何写JS库,JS库写法

    前言: 现在javascript库特别多,其写法各式各样,总结几种我们经常见到的,作为自己知识的积累.而目前版本的 JavaScript 并未提供一种原生的.语言级别的模块化组织模式,而是将模块化的方 ...

  3. 自己动手写js分享插件 [支持https] (QQ空间,微信,新浪微博。。。)

    转载:https://blog.csdn.net/libin_1/article/details/52424340 废话不多说,传送门:http://download.csdn.net/detail/ ...

  4. 自己动手写js分享插件 [支持https] (可以分享QQ空间,微信,新浪微博。。。)

    由于百度分享,jiathis 等分享插件在https下均会报错,就萌生了自己动手写一个分享插件的念头,其实实现起来一点都不难,以下代码都已在https网站运行通过,特附上以下代码:还请各位看官不吝赐教 ...

  5. 【转载】写一个js库需要怎样的知识储备和技术程度?

    作者:小爝链接:https://www.zhihu.com/question/30274750/answer/118846177来源:知乎著作权归作者所有,转载请联系作者获得授权. 1,如何编写健壮的 ...

  6. 从 0 到 1 到完美,写一个 js 库、node 库、前端组件库

    之前讲了很多关于项目工程化.前端架构.前端构建等方面的技术,这次说说怎么写一个完美的第三方库. 1. 选择合适的规范来写代码 js 模块化的发展大致有这样一个过程 iife => commonj ...

  7. 毫无保留开源我写的:IOS Android Ipad 多点触摸通用js 库

    毫无保留开源我写的:IOS Android Ipad 多点触摸通用js 库 在线演示地址: http://m.yunxunmi.com/ 支持 IOS Android Ipad 等不同操作系统的手持或 ...

  8. JS模块化编程之AMD规范(转)

    随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂. 网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者 ...

  9. 使用模块化工具打包自己开发的JS库(webpack/rollup)对比总结

    打包JS库demo项目地址:https://github.com/BothEyes1993/bes-jstools 背景 最近有个需求,需要为小程序写一个SDK,监控小程序的后台接口调用和页面报错(类 ...

随机推荐

  1. sqoop导入数据

    来源https://www.cnblogs.com/qingyunzong/p/8807252.html 一.概述 sqoop 是 apache 旗下一款“Hadoop 和关系数据库服务器之间传送数据 ...

  2. 树形dp学习

    学习博客:https://www.cnblogs.com/qq936584671/p/10274268.html 树的性质:n个点,n-1条边,任意两个点之间只存在一条路径,可以人为设置根节点,对于任 ...

  3. Linux pid与tgid概念

    在Linux操作系统层面,线程其实只是特殊的进程,最特殊之处在于跟其他“线程进程“共享内存(包括代码段.数据段等,但不共享栈). 这两天看书老是看到线程组(thread group),但是线程组是什么 ...

  4. python单元测试框架-unittest(二)之断言

    断言内容是自动化脚本的重要内容,正确设置断言以后才能帮助我们判断测试用例执行结果. 断言方法 assertEqual(a, b) 判断a==b assertNotEqual(a, b) 判断a!=b ...

  5. stm32 窗口看门狗学习(二)

    窗口看门狗有一个提前唤醒中断,如果开启这个中断,那么当计数器的值达到0x40的时候就会产生这个中断. 上次的代码加一点就可以做这个实验了. void WWDG_Init(u8 tr,u8 wr,u32 ...

  6. 自定义Qt组件-通讯模块(P3)

    1.   半双工模式实时检测串口 ComHalfDuplex类是为了解决上位机发送控制指令和下位机发送数据会在半双工RS485总线中产生冲突引起乱码而引入的(v0.010版本引入). 解决冲突的原理主 ...

  7. GitKraken使用教程-基础部分(6)

    4) 放弃本次文件的改动 有些情况下,由于更改代码造成了编译无法通过等错误时,想要放弃这次对文件的修改,将文件还原成上一次提交后的状态,一种简单的恢复文件的方法就是,在Unstaged Files 列 ...

  8. HDU 4336——Card Collector——————【概率dp】

    Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. [转]Asp.net Core中使用Session

    本文转自:http://www.cnblogs.com/sword-successful/p/6243841.html 前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. ...

  10. Python四大神兽(迭代器&生成器&闭包&装饰器)

    一.迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式.. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不 ...