模块化

模块化

  1. 定义: 将程序分成一个个小的模块,在这个模块中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他的结构。整个模块可以将自己希望暴露的变量、函数、对象等导出给其它模块使用;也可以通过某种方式,导入另外模块中的变量、函数、对象等。

  2. CommonJS [Node/WebPack]
    (1) 在Node中每一个js文件都是一个单独的模块
    (2) CommonJS规范的核心变量: exports、module.exports、require

    exports.name = 'nano'
    
    module.exports = { name: ' nano' }
    
    const foo = require('文件名')
  3. 变量分析
    (1) exports & module.exports
    定义: 负责对模块中的内容进行导出

(2) require
定义: 是一个函数,可以帮助我们导入其它模块(自定义模块、系统模块、第三方库模块)中的内容
i. module.exports & require

/* a.js */
let name = 'nano'
let foo = function(){}

/* 直接导出 */
module.exports = {
  name, foo
}

/* 导出集合对象  */
let obj = { name,foo }
module.exports = obj

/* b.js */
const modeulA = require('./a.js')
console.log( moduleA ) --> { name: 'nano',foo:function(){} }

注意: 最终导出都是以module.exports对象的形式被导出,所以一般都是用module.exports进行导出

ii. exports(不推荐)

a.js
let name  = 'nano'
exports.name = name

b.js
const res = reuiqre( './a.js' )
cosnole.log(  res ) --> { name: nano }

/* 源码解析 */
module.export = {}
// 因为将module.export的地址赋值给exports,所以可以用exports导出,实际还是导出module.exports对象
exports = module.export
exports.name = name

require

  1. 定义: require是一个函数,用来导入其他模块或者依赖包(核心模块)
  2. 查找规则:
    (1) 如果是核心模块:
    直接引入后使用
    (2) 如果是路径:
    没有写文件后缀,则按照 x.js -> x.json -> x.node
    写了文件后缀: 直接查找文件
    (3) 如果既不是核心模块也不是路径:
    逐层向上查找每层的node_modules中是否有同名文件夹,找到之后自动寻找index.js文件作为引入

CommonJS的原理

  1. 声明的需要导出的对象、exports导出的对象、module.exports 导出的对象 与 require导入的对象都指向同一个地址

模块的加载过程(Common.js)

  1. 模块在被第一次引入时,模块中的js代码会被运行一次
  2. 模块被多次引入时,会被缓存,最终只加载(运行)一次
    (1) 每个模块对象都有一个属性loaded,false表示未加载,true表示已加载
    (2) 重复引用的模块指针都是指向同一个地址,所以只会加载一次
  3. 循环引入的加载顺序(图结构):
    (1) 按顺序执行require函数,如果里面还有require函数则继续执行 [深度优先搜索]
    (2) 如果有不同模块引用了相同的模块,则执行优先引入的那个模块,后续因为缓存不执行引入 [广度优先搜索]

CommonJS缺点

  1. 加载模块是同步的,意味着只有将模块资源全部加载完成后才能执行下一步的代码,不适用于浏览器。
  2. 浏览器的js文件需要先从服务器下载再进行加载,这意味着后面的js代码都无法继续执行,是无法接受的,而服务器是读取本地资源,速度很快,所以没有影响。

AMD (了解)

  1. 定义: 异步加载模块

CMD (了解)

  1. 定义: 异步加载模块和CommnonJS的优点

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!