Commonjs规范
- 关于CommonJS规范
- 诞生的目的就是为了弥补浏览器没有模块化缺陷
- CommonJS是语言层面的规范,是一个超集,当前主要用于Nodejs
- CommonJS规范规定模块化分为引入(通过rrquire导入其他模块)、定义(任意一个文件就是一个模块,具有独立作用域)、标识符(将模块ID传入require实现目标模块定位)三个部分
- module属性
- 任意js文件就是一个模块,可以使用module属性
- id:返回模块标识符,一般是一个绝对路径
- filename:返回文件模块的绝对路径
- loaded:返回布尔值,表示模块是否完成加载
- parent:返回对象,调用当前模块的模块
- children:返回数组,当前模块要调用的其他模块
- exports:返回当前模块要暴露的内容
- paths:返回不同目录下的node_modules位置
- module.exports 与exports的区别
- 在commonjs规范中只规定了使用module.exports导出数据
- 是nodejs为了方便,给每个模块加了一个exports指向module.exports的内存地址
- 但是不能直接给exports赋值,这样它就指向新的内存地址
- requir属性
-
基本功能是读入并且执行一个模块文件返回这个对象里的exports对象,如果没有找到该模块会报错
(加载即执行了吗)
- resolve:返回模块文件绝对路径
- extensions:依据不同后缀名执行解析操作,根据不同的后缀名执行不同的执行函数,.js,.json,.node,省略不写会依次判断
- main:返回主模块对象
导入导出示例
新建module.js文件
const age = 18
const addFN= (x,y)=>{
return x+y
}
module.exports = {
addFN,
age
}
新建01.js文件
let obj = require('./module')
console.log(obj,'oooo')
执行node 01 得到如下结果:{ addFN: [Function: addFN], age: 18 }
那之前我们说过每个文件都是一个独立的模块,模块内可以使用module属性,那假设我们在01.js中打印module会发生什么呢?
let obj = require('./module')
console.log(module)
其中
- id 是模块标识
- path是文件所在的父级路径
- exports是一个对象,代表本模块要导出的内容,这里没有导出故而为空对象
- parent是指谁引用了我
- filename是指文件绝对路径
- loaded是否加载完成
- children是表明此模块引入了哪些子模块,我们引入了module.js这个模块
- paths:表示node_modules查找顺序
注意:
- exports是nodejs为了方便使用写的语法糖,指向与module.exports同一内存地址,一旦我们对其重新赋值则切断了联系也无法完成导出
//module.js
const age = 18
const addFN= (x,y)=>{
return x+y
}
exports = {
addFN,
age
}
let obj = require('./module')
console.log(obj,'oooo') // 结果为{}
- 我们可以通过exports[属性名]的方式进行导出,导出操作是生效的
//module.js
const age = 18
const addFN= (x,y)=>{
return x+y
}
exports.addFN = addFN
exports.age = age
let obj = require('./module')
console.log(obj,'oooo') // 结果为{ addFN: [Function: addFN], age: 18 } oooo
- 如果我们没有导出,则别人加载后是一个{},因为module.exports默认是{}
同步加载
在CommonJS中,非核心模块的加载是同步加载,也就是说假设我们引入的组件耗时,那会等待加载完成继续向下执行。
//module.js
const age = 18
let nTime = new Date()
while(new Date()-nTime<4000){
}
exports.age = age
console.log('页面导出完成')
let obj = require('./module')
console.log('加载完成')
命令行执行node 01之后是隔4秒钟后打印如下内容:
页面导出完成
加载完成
注意:
- 可以判断,我们导入某个模块,是先把模块的内容以同步的方式装载到系统中,如果装载的过程中模块存在问题,则会导致程序中断执行,有点类似于同步引入js的那种感觉
//module.js
const age = 18
age = 20
exports.age = age
//01.js
let obj = require('./module')
console.log(obj)
console.log('加载完成');
执行结果如下:
- 如果要加载多个模块,需要加载完第一个模块才会加载后续模块,在浏览器中同步加载会导致性能低下,因此不适合于浏览器
版权声明:本文为liuliuliuliumin123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。