起源
javascript当初被设计出来用于浏览器,js的能力大小取决于运行环境对于api的支持能力。在web的发展中,浏览器中出现了更多标准api,但是后端javascript规范却远远落后。对于javscsript语言而言, 它薄弱环节是缺少规范:
- 没有模块系统
- 标准库少
- 没有标准接口
- 缺乏包管理系统
commonJS规范的提出,主要是弥补了js没有标准的缺陷,以具备开发大型应用的基础能力,而不是停留在小型脚本的处境。在发展中,commonJS的成长中,规范涵盖了模块、二进制、buffer、字符集编码、i/o流、进程环境、文件系统、套接字、单元测试、tcp/ip、包管理等。
commonJS规范
- 模块引用:使用
require()引用一个模块 - 模块定义:在模块中,上下文提供require()引入外部模块,导入相应功能。上下文提供了export()方法导出当前模块的方法或者变量。并且这是唯一到导出出口。模块中还存在一个module对象。他代表模块自身,export是module的属性。在node中,一个文件就是一个模块
- 模块标示:模块标示就是传递给require()的参数,内部模块可以是驼峰字符串,自己写的模块可以使相对路径和绝对路径,可以忽略后缀名。
Node的模块实现
先上图:
如果目标文件为json,会通过JSON.parse()转化后返回。
如果目标文件为.node,会通过dlopen()方法进行加载。
如果目标文件为.js,先在读取的文件字符串首尾依次拼接(function(){和}),目的是解析执行时为模块代码添加一个封闭作用域。然后调用vm原生模块的runInThisContext()方法执行。返回一个具体的function对象。不会污染全局。最后call()执行。