学习笔记—Node中模块化规范

日常的学习笔记,包括 ES6、Promise、Node.js、Webpack、http 原理、Vue全家桶,后续可能还会继续更新 Typescript、Vue3 和 常见的面试题 等等。


模块化与全局对象

参考文献 Global objects|Node.js

首先,模块化包括 require()exportsmodule 等。

console.log(global.exports); // undefined
console.log(global.module); // undefined
console.log(global.require); // undefined

但是当我们在控制台打印时,发现其结果都是 undefined。我们却可以直接对这些属性进行访问,比如console.log(require)

这里需要注意,global上有的属性叫做全局属性,可以直接访问。但 require()exportsmodule 也可以直接访问,但是他们却不在global对象上。

每个文件都是一个模块,模块化的实现借助的是函数。

而这个函数里面有五个参数,分别是 __dirname__filenamerequire()exportsmodule(后续我会写一篇文章来实现模块化)

模块化的规范

模块化规范包括以下几种

  • CommonJs规范
  • ESModule规范
  • AMD
  • CMD
  • UMD
  • SystemJs
  • ...

为什么要有模块化规范?

JS 诞生的时候,仅仅是为了实现网页表单的本地校验和简单的 dom 操作处理。所以并没有模块化的规范设计。

项目小的时候,我们可以通过命名空间、局部作用域、自执行函数等手段实现变量不冲突。但是到了大一点的项目,各种组件,各种第三方插件和各种 js 脚步融合的时候,就会发现这些技巧远远不够。

单例模式

最早的时候,一些项目组会采用 单例设计模式 来解决这个问题。

// 成员a
var a = {
  aa(){ 
  }
	// do something...
}
// 成员b
var b = {
  bb(){
  }
	// do something...
}

这种解决方式就会出现 命名过长,难以调用 等问题。所以他 解决了,但没有完全解决

AMD、CMD

为了解决模块化的问题,人们用 文件拆分 的方式,配合 iife **自执行函数 **来解决。也就是 AMD、CMD

let xx = (function(){
  // ...
  return obj
})()

这种方式在前端中需要请求顺序,也就出现了依赖问题。比如我们现在有一个文件a,他需要依赖文件b和文件c,但是c文件又需要依赖文件d。这时候就出现了文件之间的依赖问题,我们并不知道每个文件需要依赖的文件都有谁。

这就是以前出现的依赖前置 define(['jquery','xxx'],function(){ // ... })

UMD

它可以通过运行时或者编译时让同一个代码模块在使用 CommonJs、CMD 甚至是 AMD 的项目中运行。未来同一个 JavaScript 包运行在浏览器端、服务区端甚至是 APP 端都只需要遵守同一个写法就行了。

简单来说,他的出现就是为了兼容CommonJs、CMD和AMD,但是他并不兼容ESModule(所以我们在平时发布组件库时,就会将代码打包成 UMD 和 ESModule 两种)

CommonJs和ESModule的区别

CommonJsESModule 的定义都是一样的,一个文件就是一个模块

  • CommonJs的用法require() 是使用其他模块,module.exports 是导出模块。
  • ESModule的用法import 是使用其他模块,export 是导出模块。

CommonJs基于Node的I/O操作,如果我想进行模块的引入和导出,我就需要使用Node来进行操作。

ESModule基于浏览器的请求,如果我想进行引入导出的操作,我就需要使用浏览器。

我们也可以理解为,ESModule 是静态的,而 CommonJs是动态的。所以我们平时才会使用 require() 来对资源进行动态引入。 (注:目前ES7中支持 import('./xxx')来对资源进行动态引入)

// ESModule不可以动态引入资源
if(true){
  // 这种写法不成立
  import xxx from './xxx'
}
// CommonJs可以动态引入资源
if(true){
  require('./xxx')
}

(在现在的实际项目中,我们一般会使用webpack来对文件进行自动编译。)

本篇文章由莫小尚创作,文章中如有任何问题和纰漏,欢迎您的指正与交流。
您也可以关注我的 个人站点博客园掘金,我会在文章产出后同步上传到这些平台上。
最后感谢您的支持!

上一篇:CommonJS与ES Module模块化开发导入、导出


下一篇:commonJS简单实现