【青训营】- 模块化 JS 初步理解CommonJS

316 阅读2分钟

模块化 JS 初步理解CommonJS

模块化的开发方式可以提高代码复用率,方便进行代码的管理。通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。目前流行的js模块化规范有CommonJS、AMD、CMD以及ES6的模块系统。

为什么模块化?

  • 解决命名冲突,全局污染
  • 模块内部逻辑的封装性隔离
  • 模块之间的通讯(依赖引用、循环引用、引用顺序)

目前大部分的模块化方案都是以闭包为基础的,那么什么是闭包?

 (function() {
   var privateCounter = 0;
   function changeBy(val) {
     privateCounter += val;
   }
   return {
     increment: function() {
       changeBy(1);
     },
     decrement: function() {
       changeBy(-1);
     },
     value: function() {
       return privateCounter;
     }
   }
 })

可以初步理解为私有方法,名为 privateCounter 的变量和名为 changeBy 的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。

CommonJS

 // greeting.js
 const prefix = 'hello';
 const sayHi = function() {
     return prefix + 'world';
 }
 module.exports = {
     sayHi
 }
 ​
 // index.js
 const { sayHi } = require('./greeting');
 sayHi();

我们使用 module.exports 导出了 sayHi 函数,而在 index.jsgreeting.js 的其他变量并不可以访问。

在编译的过程中,实际 CommonJSJS 的代码块进行了首尾包装, 我们以上述的 greeting.js 为例子,它被包装之后的样子如下:

 (function(exports,require,module,__filename,__dirname){
     const prefix = 'hello';
     const sayHi = function() {
         return prefix + 'world';
     }
     module.exports = {
         sayHi
     }
 })

和上边示例的闭包是不是有些相似?

require() 返回值就是 module.exports,所以,在 index.js 中使用的 require() 本质上也是一个函数,使用 const {} = require('') 赋值很像是解构赋值,比较一下是不是全都对上了。

总结

这篇文章实在太好了,有时间可以仔细看看!

引用参考