谨以此文记录了解js模块的过程

随着ES6的出现,js模块已经成为正式的标准了。曾经为了解决js模块问题而发展起来的民间秘籍,requireJs(AMD)、SeaJs(CMD)、Node(CommonJs),已经或者不久的将来会成为历史。了解历史也是很重要的,因为正式标准就是以民间秘籍为基础而发展起来的,有些规范仍然被广泛应用于开发中(CommonJS)。再者,进入有些公司,你的工作可能是继承前辈们的代码,为了不至于始终一脸懵,认识一下这些东西是很重要的。

关于js模块的发展历史

github上玉伯发表的issue:地址

CommonJs模块规范

  • 用于同步加载模块
  • 主要应用于服务端

关于CommonJS的说明:commonjs

Node参考CommonJS实现了一套模块系统,npm上有大量的CommonJS的包,ECMAScript取代CommonJS可能还需要一些时日。

CommonJs对模块的定义很简单,主要分为模块引用、模块定义和模块标识。

模块引用

使用require()方法,该方法接收模块标识,引入一个模块的API到当前上下文。

var math = require("math");
math.add();

模块定义

上下文提供exports对象用于导出当前模块的方法或者变量,并且它是唯一导出的出口。module对象,代表模块自身,exports是module的属性。将方法挂载在exports对象上作为属性即可定义导出的方式。

exports.add = function () {
var sun = 0,
i = 0,
args = arguments,
l = args.length; while (i < 1) {
sum += args[i++];
}
return sum;
}

模块标识

模块标识是传递给require()方法的参数,它必须是符合小驼峰命名的字符串,或者以.,..开头的相对路径,或者绝对路径。它可以没有文件名后缀.js。

优势

  1. 语法简单,只需要定义module.exports属性,剩下的模块代码与标准Javascript无差异。引用模块的方法也很简单,只需要使用require函数
  2. CommonJS是Node.js默认的模板格式,所以我们可以是用成千上万的包

缺点

  1.  最大的缺点就是不显示的支持浏览器,(浏览器端的javascript不支持module变量和export属性,当然也有方法可以在浏览器中使用CommonJS模块,可以查看这里)由此也产生了另外的用于前端浏览器的规范AMD

AMD与requireJS

AMD是CommonJS的一个延伸,制定了能够在前端应用的模块规范。

  • 异步加载模块
  • 主要用于浏览器

github中AMD的定义——地址

规范

// 模块定义
// id和dependencies都是可选的
// factory是模块的实际代码
define(id, dependencies, factory); define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function () {
return beta.verb();
//Or:
return require("beta").verb();
}
});
// 不带id(名称)
define(["alpha"], function (alpha) {
return {
verb: function () {
return alpha.verb() + 2;
}
};
});
// 不带名称和依赖
define({
add: function (x, y) {
return x + y;
}
}); // 引用模块
// module是要加载的模块
// callback在加载完成之后运行
require([module], callback)
require(['a', 'b'], function (a, b) {
//modules a and b are now available for use.
});

优势

  1. 自动处理依赖,无序考虑引入顺序
  2. 异步加载模块,避免阻塞

requireJS

requireJS实现了AMD规范,具体使用方法请移步——中文API

CMD与SeaJS

CMD是玉伯在学习requireJs的过程中,自己提出的一个规范。SeaJs作为实现该规范的工具,一度成为与requireJs并肩的工具(当然主要是在国内)

玉伯在2015年宣布Seajs已死。ES2015正式发布了。不再需要民间力量修补这个漏洞了。

ES6Module

以上所有规范都是ES6之前产生的,为ES6奠定了基础。ES6汲取了CommonJS和AMD的优点:

  • 与CommonJS类似,语法简单,一个文件是一个模块
  • 与AMD类似,同样支持异步加载模块

语法

http://es6.ruanyifeng.com/#docs/module

总结

CommonJS规范,语法简单、同步加载、主要应用于服务端。目前在Node中仍然占据重要地位。

AMD规范,作为CommonJS的延伸,语法略微复杂一些,异步加载,主要应用于浏览器。

ES6 Module作为javascript内置的模块标准,虽然浏览器目前并不完全支持,但是有Babel等转换器,帮助转换ES6语法到ES5语法,从现在开始学习并应用ES6,也许是比较好的选择。

参考

  1. js模块发展历史——地址
  2. 知乎上玉伯关于CMD和AMD的区别的回答——地址
  3. require.js——中文官网
  4. 《深入理解es6》
  5. exploringJs——https://exploringjs.com/es6/

javascript的模块发展的更多相关文章

  1. 研究一下javascript的模块规范(CommonJs/AMD/CMD)

    最近写react需要使用nodejs作为开发环境,需要通过npm安装一些第三方的依赖库,因此慢慢感觉到nodejs基础薄弱对我带来了一些不安全感,尤其是javascript模块这一块听到了很多概念,比 ...

  2. seajs实现JavaScript 的 模块开发及按模块加载

    seajs实现了JavaScript 的 模块开发及按模块加载.用来解决繁琐的js命名冲突,文件依赖等问题,其主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载. 官方文档:http:/ ...

  3. JavaScript中模块“写法”

    在JavaScript模块到底是什么 event = function() { // do more return { bind: function() {}, unbind: function() ...

  4. 在浏览器中高效使用JavaScript module(模块)

    在浏览器中也可以使用JavaScript modules(模块功能)了.目前支持这一特性的浏览器包括: Safari 10.1. 谷歌浏览器(Canary 60) – 需要在chrome:flags里 ...

  5. python与javascript 引入模块的方法对比

    1.引入整体模块对比 python 方法一: # 引入全部函数 from xxx import * # 直接使用模块里面的各函数或者属性 test() 方法二: # 引入全局的模块 import gl ...

  6. javascript 异步模块加载 简易实现

    在javascript是没有类似java或其他语言的模块概念的,因此也不可能通过import或using等关键字来引用模块,这样造成了复杂项目中前端代码混乱,变量互相影响等. 因此在复杂项目中引入AM ...

  7. JavaScript AMD 模块加载器原理与实现

    关于前端模块化,玉伯在其博文 前端模块化开发的价值 中有论述,有兴趣的同学可以去阅读一下. 1. 模块加载器 模块加载器目前比较流行的有 Requirejs 和 Seajs.前者遵循 AMD规范,后者 ...

  8. [JavaScript] 前端模块加载简单实现(require)

    模块加载的简单实现 (function(win) { var baseUrl; var paths; var script_cache = {}; var script_queue = []; var ...

  9. [JavaScript] 前端模块编程实现

    前端模块化 前端早期写代码都是全局变量满天飞,这种情况会造成全局命名空间污染,变量冲突等问题 var a = 1; var b = 2; function c(){} function d(){} 后 ...

随机推荐

  1. 洛谷3384&bzoj1036树链剖分

    值得注意的是: 一个点的子树是存在一起的...也就是说我们修改子树的时候只用... /********************************************************* ...

  2. 洛谷【P1177】【模板】归并排序

    题目传送门:https://www.luogu.org/problemnew/show/P1177 归并排序: 1.先将\(a\)数组的区间\([l,mid],[mid+1,r]\)排成有序的. 2. ...

  3. 关于Snoop的用法

    snoop是开发wpf应用程序的利器.用它可以观察WPF的可视树,监听事件,更改元素属性等. 下面我介绍下snoop一些用法. 1.获取指定应用程序的UI   打开snoop,选择"Drag ...

  4. 使用TortoiseGit来访问GitHub

    因为以前一直在用TSVN, 对其界面操作比较熟悉. 因此,决定不用Git Gui而是用TortoiseGit来访问GitHub. 安装TortoiseGit成功后, 1.运行PuTTY Key Gen ...

  5. Python selenium 三种等待方法

    1. 强制等待 sleep(xx) 是最简单粗暴的一种办法,不管你浏览器是否加载完了,程序都得等待3秒,3秒一到,继续执行下面的代码,作为调试很有用,不建议总用这种等待方式,严重影响程序执行速度. 代 ...

  6. Python-Redis的Hash操作

    Redis的hash是一个string类型的field和value的映射表,特别适合用于存储对象,每个hash可以存储40多亿键值对 hset(name, key, value):创建一个name的类 ...

  7. 怎么查看mysql的安装目录,环境:windows+mysql+navicat

    怎么查看mysql的安装目录 如果忘记了MySQL的安装目录,怎么快速找到呢?方法或许很多,作者觉得这种最方便了 环境:windows+mysql+navicat 方法:进入mysql命令行输入:sh ...

  8. LAMP 1.2 Apache编译安装问题解决

    这个错误安装 yum install -y gcc error: mod_deflate has been requested but can not be built due to prerequi ...

  9. 调试opencv调用摄像头程序时碰到的问题

    昨天晚上想把opencv学习笔记整理一下,当跑opencv调用摄像头的程序的时候老是出现Assertion failed (size.width>0 && size.height ...

  10. CSDN优秀博客连接,博客之星连接。

    点击链接 获得[红杏出墙]插件,FQ上网无压力!谷歌搜索无压力! 2013年度CSDN十大博客之星 TOP 作者 专注领域 博客地址 邹晓艺 机器学习及算法 zouxy09 2 王然 潜在的集大成者 ...