CommonJS是由javascript社区提出的一套包含模块、文件、IO、控制台在内的一系列标准。
1、模块
CommonJS中规定每个文件是一个模块,将一个js文件直接通过script标签插入页面中与封装成CommonJS模块最大的不同在于,前者的顶层作用域是全局作用域,在进行变量以及函数声明的时候会污染全局环境。后者会形成一个属于模块自身的作用域,所有的变量以及函数只能自身模块去访问,对外是不可见的。
示例:
- getInfo.js:
export var name = 'getInfo.js中的name'
- index.js:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
require('./src/index.js')
var name = 'index.js中的name';
console.log(name);
node在升级之后,对 require 的使用方法发生了改变。从node.js 14版及以上版本中,require作为COMMONJS的一个命令已不再直接支持使用,所以我们需要导入createRequire命令才可以。
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
2、导出
导出是一个模块向外暴露自身的唯一方式,在CommonJS中,通过module.exports可以导出模块的内容。
module.exports = {
name: 'e-kr',
add: function(a,b) {
return a+b;
}
}
CommonJS模块内部会有一个module对象用于存放当前模块的信息,默认是有一个主体的对象module的,不进行逻辑操作的话相当于导出的module空对象的。
export.name = 'e-kr';
exports默认指向了module.exports
3、导入
在CommonJS中使用require进行模块导入时,
// getInfo.js
module.exports = {
add: function(a,b) {
return a+b;
}
}
// index.js
const info = require('./getInfo');
const sum = info.add(2,3);
console.log(sum);
在index.js中导入getInfo模块,并调用它的add函数方法,当我们require一个模块时会产生两种情形:
- 1、require的模块是第一次被加载,这时会首先执行这个模块,然后再导出内容
- 2、require的模块是之前被加载过的,这时该模块的代码不会再次执行,而是直接导出之前执行过的结果。
出现这种情况的原理是:
模块中有一个module对象专门用来存放其信息,这个对象中有一个属性loaded用于记录该模块是否被加载
过,它的默认值是false,当模块第一次被加载和执行过后会变成true,后面再次加载时检测到module对象中的loaded属性为true的话就不会再去执行模块代码。
有时加载一个模块,不需要获取其导出的内容,只想通过执行它而产生某种作用,直接使用require即可。
此外,require函数可以接收表达式,这个特性可以动态的给我们指定模块的加载路径。
const moduleNames = ['foo.js', 'bar.js'];
moduleNames.forEach( name => {
require('./' + name);
})
网友评论