前端模块化:CommonJS,AMD,CMD,import/export

模块化的开发方式可以提高代码复用率,方便进行代码的管理。通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。目前流行的js模块化规范有CommonJS、AMD、CMD(前三者是ES5中提供的)以及ES6的模块系统import/export

CommonJS

Node.js是commonJS规范的主要实践者,它有四个重要的环境变量为模块化的实现提供支持:module、exports、require、global

实际用时,使用module.exports(不推荐使用exports)定义对外输出的API,用require来引用模块。

CommonJS对模块的定义主要分为:模块引用、模块定义、模块标识3个部分。

  1. 模块引用 ——const fs = require('fs');

  2. 模块定义
    function fn() {} exports.propName = fn; module.exports = fn;

AMD(Asynchronous Module Definition)

AMD,异步模块定义。AMD不是javascript原生支持,它是RequireJS在推广的过程中对模块定义的范围化的产出。所以使用AMD规范进行页面开发需要用到对应的库,也就是RequireJS。

requireJS主要解决两个问题:

  • 多个js文件存在依赖关系时,被依赖的文件需要早于依赖它的文件加载到浏览器
  • js加载的时候浏览器会阻塞渲染线程,加载文件越多,页面失去响应的时间越长

CMD(Common Module Definition)

CMD, 通用模块定义。 CMD是在SeaJS推广的过程中产生的,是一个同步模块定义(CMD是依赖就近,在什么地方使用到插件就在什么地方require该插件,即用即返)。在CMD规范中,一个模块就是一个文件。

AMD/CMD比较

  • 定义module时对依赖的处理

    • AMD推崇依赖前置,在定义的时候就要声明其依赖的模块
    • CMD推崇就近依赖,只有在用到这个module的时候才去require
  • 加载方式

    • AMD: async
    • CMD: sync
  • 执行module的方式

    • AMD加载module完成后就会执行该module,所有module都加载执行完成后会进入require的回调函数,执行主逻辑。依赖的执行顺序和书写的顺序不一定一致,谁先下载完谁先执行,但是主逻辑 一定在所有的依赖加载完成后才执行(有点类似Promise.all)。
    • CMD加载完某个依赖后并不执行,只是下载而已。在所有的module加载完成后进入主逻辑,遇到require语句的时候才会执行对应的module。module的执行顺序和书写的顺序是完全一致的。

ES6 Module

ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,旨在成为浏览器和服务器通用的模块解决方案。

其模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

ES6 Modules不是对象,import命令会被 JavaScript 引擎静态分析,在编译时就引入模块代码,而不是在代码运行时加载,所以无法实现条件加载。也正因为这个,使得静态分析成为可能。

ES6模块/CommonJS模块比较

1、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用

  • CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
  • ES6 Modules 的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。换句话说,ES6 的 import 有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

2、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口

  • 运行时加载: CommonJS 模块就是对象;即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。
  • 编译时加载: ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载”。
posted @ 2019-08-06 10:06  sunidol  阅读(868)  评论(0编辑  收藏  举报