CommonJS规范简介
By Alex
/ in JavaScript
在ES6之前,JavaScript语言一直缺乏语言级别的模块化机制,这促使了CommonJS、AMD的项目的诞生与发展。
模块化要解决的基本问题包括:
- 全局命名空间污染。所谓污染是指属于库/框架的实现细节的变量/函数暴露为全局变量,导致可能的意外覆盖发生
- 按需加载代码。如何在运行时动态的加载用到的JavaScript代码,而不是一股脑的、在程序初始化时全部载入内存
- 依赖管理。在实现按需加载的同时,还能够自动管理模块之间的依赖关系
CommonJS是一种JavaScript模块化规范,最初由Mozilla创建,用于服务器端JavaScript程序。
简单示例
CommonJS规定每个JS文件对应一个模块 ,模块必须使用 module.exports 来导出需要对外暴露的变量。任何变量可以被导出,例如函数、对象:
1 2 3 |
module.exports = function ( value ) { return value * 2; } |
如果代码需要依赖某个模块导出的变量,则必须使用 require 来导入,此导入是同步化执行的:
1 2 |
var doubleOf = require( './moduleA' ); var result = doubleOf( 2 ); |
require的入参是一个字符串,是目标模块的路径(作为模块标识符),不带.js后缀。 require的返回值就是目标模块的module.exports。
规范内容
本节简单翻译一下CommonJS模块化版本1.1的内容。
模块上下文
- 在模块中,必须有一个自由变量require,它是一个函数
- require函数接受外部模块的标识符(module identifier)作为入参
- require返回外部模块(foreign module)导出的API
- 如果存在循环依赖,则在require调用时外部模块可能尚未执行完毕。这种情况下require的返回值必须包含外部模块已经准备好的导出API
- 如果请求的外部模块无法找到,则require函数抛出异常
- require函数可以具有一个main只读属性,如果提供该属性,则它指向主程序的“模块”对象
- require函数可以具有一个paths属性,它是路径的数组,元素用于指定顶级模块所在目录,优先级依次降低。path属性类似于PATH环境变量
- 在模块中,必须有一个自由变量exports,该变量是一个对象,模块将其需要导出的API添加到此变量中
- 模块必须使用exports对象作为唯一的导出路径
- exports的最初值是指向module.exports的引用,后者的最初值则是一个空对象
- 在模块中,必须有一个自由变量module,该变量是一个对象
- “模块”对象必须具有一个只读的id属性,表示该模块的顶级(top-level )标识符。此标识符被require函数使用
- “模块”对象必须具有一个uri属性,表示模块对应的资源的全限定URI
模块标识符
- 模块标识符是字符串,由正斜线分割为多个term
- 每个term必须是驼峰式大小写JS标识符、 . 或者 ..
- 顶级标识符基于模块命名空间的根(conceptual module name space root)进行解析
- 相对标识符相对于require发起模块的标识符进行解析
Flux架构简介 →
Leave a Reply