模块化编程:CommonJS、AMD、ES6模块化

[TOC]

历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。

下面比较现有的三种模块化编程方案:

  • CommonJS
  • AMD
  • ES6

比较:

  • CommonJS大多数用于服务器端开发,运行时加载
  • AMD大多数用于浏览器客户端开发,运行时加载
  • ES6:编译时加载,尽量实现静态化

    CommonJS

  • 一般用于服务器端
  • NodeJS是CommonJS规范的实现
    1
    2
    var math = require('math');
    math.add(2,3); // 5

require是同步的


AMD(异步模块定义)

  • 一般用于浏览器客户端
  • 包含:RequireJs
    require是同步的对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于”假死”状态。
    因此,浏览器端的模块,不能采用”同步加载”(synchronous),只能采用”异步加载”(asynchronous)。这就是AMD规范诞生的背景。
    AMD也适用require,但是使用回调函数执行后面动作
    1
    2
    3
    4
    5
    require(['math'], function (math) {
        math.add(2, 3);
      });

ES6

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性

  • ES6可以通过模块接口取到模块内部实时的值,这一点与 CommonJS 规范完全不同,CommonJS 模块输出的是值的缓存,不存在动态更新
  • ES6的模块化是在编译时加载的,有作用域提升的效果
  • ES6中import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构

【潦草记录】

热评文章