CommonJS规范

1 CommonJS规范

CommonJS规范中,每个文件都可以当做一个模块,并且模块的加载是同步阻塞的,也是缓存的
在服务器端,NodeJS本身实现了CommonJS
在浏览器端,在使用Browserify编译之后可以支持CmmonJS

1.2 服务器端

Node环境中,一般使用module.exports或exports, 将要暴露的变量设置成module.exports的属性

2.1.1 暴露模块

// case1
module.exports = {
    fn:()=>console.log('m1 fn')  // output:{ fn: [Function: fn] }
}

// case2
exports.fn = ()=>console.log('m1 fn') // output:{ fn: [Function: fn] }

// case3 
exports = {
    fn:()=>console.log('m1 fn') // output:{ }
}

case1和case2实际上没什么区别,因为模块暴露本质上暴露的是module对象中的exports属性。
对于case3,exports可以看做是module.exports的引用,一旦改变了exports的引用,使得exports变量不再指向module.exports,那么exports也就和module对象无关了,也就是说与模块暴露的内容无关了

Module对象:

Module {
  id: 'C:\\Users\\module\\m1.js',
  path: 'C:\\Users\\module',    

  // 模块暴露的内容
  exports: {},

  
  parent: Module {
    id: '.',
    path: 'C:\\Users',
    exports: {},
    parent: null,
    filename: 'C:\\Users\\app.js',
    loaded: false,
    children: [ [Circular] ],
    paths: []
  },
  filename: 'C:\\Users\\module\\m1.js',
  loaded: false,
  children: [],
  paths: []
  children: [],
  paths: []
}

2.2.2 引入模块

Node环境中,一般使用require引入模块,模块在运行时加载,并且具有缓存特性,即在一个文件中多次引入同一模块,模块中的代码不会重复执行,而是直接从内存中读取模块暴露的内容

// m1
console.log('m1 loading')
exports.fn = () => console.log('m1 fn')
// m2
console.log('m2 loading')
exports.fn = () => console.log('m2 fn')
// 引入
let module1 = require('./module/m1')
let module2 = require('./module/m2')
module1.fn()
module2.fn()

/* 
output:
m1 loading
m2 loading
m1 fn
m2 fn
*/

重复引入m2,由于存在缓存的原因只输出一次m2 loading

let module1 = require('./module/m1')
let module2 = require('./module/m2')
module1.fn()
module2.fn()

let _module2 = require('./module/m2')
JSON.stringify(_module2)

/* 
output:
m1 loading
m2 loading
m1 fn
m2 fn
*/

1.3 浏览器端

浏览器引擎不能识别require,因此可以使用script引入browserify编译之后的文件来执行

安装:
npm install browserify -g

编译并输出:
browserify js/src/app.js -o js/dist/bundle.js

使用:

<script type="text/javascript" src="js/dist/bundle.js"></script> 

1.4 总结

  1. 模块运行时执行,并且存在缓存,多次导入不重复执行模块代码。 ESM是模块加载时执行
  2. exports只是module.exports的一个引用
  3. 浏览器端不支持require语法,可以结合browserify编译之后使用
  4. 导出的是模块的拷贝
posted @ 2022-03-24 20:46  IslandZzzz  阅读(158)  评论(0编辑  收藏  举报