模块化
模块化
定义: 将程序分成一个个小的模块,在这个模块中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他的结构。整个模块可以将自己希望暴露的变量、函数、对象等导出给其它模块使用;也可以通过某种方式,导入另外模块中的变量、函数、对象等。
CommonJS [Node/WebPack]
(1) 在Node中每一个js文件都是一个单独的模块
(2) CommonJS规范的核心变量: exports、module.exports、requireexports.name = 'nano' module.exports = { name: ' nano' } const foo = require('文件名')
变量分析
(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
- 定义: require是一个函数,用来导入其他模块或者依赖包(核心模块)
- 查找规则:
(1) 如果是核心模块:
直接引入后使用
(2) 如果是路径:
没有写文件后缀,则按照 x.js -> x.json -> x.node
写了文件后缀: 直接查找文件
(3) 如果既不是核心模块也不是路径:
逐层向上查找每层的node_modules中是否有同名文件夹,找到之后自动寻找index.js文件作为引入
CommonJS的原理
- 声明的需要导出的对象、exports导出的对象、module.exports 导出的对象 与 require导入的对象都指向同一个地址
模块的加载过程(Common.js)
- 模块在被第一次引入时,模块中的js代码会被运行一次
- 模块被多次引入时,会被缓存,最终只加载(运行)一次
(1) 每个模块对象都有一个属性loaded,false表示未加载,true表示已加载
(2) 重复引用的模块指针都是指向同一个地址,所以只会加载一次 - 循环引入的加载顺序(图结构):
(1) 按顺序执行require函数,如果里面还有require函数则继续执行 [深度优先搜索]
(2) 如果有不同模块引用了相同的模块,则执行优先引入的那个模块,后续因为缓存不执行引入 [广度优先搜索]
CommonJS缺点
- 加载模块是同步的,意味着只有将模块资源全部加载完成后才能执行下一步的代码,不适用于浏览器。
- 浏览器的js文件需要先从服务器下载再进行加载,这意味着后面的js代码都无法继续执行,是无法接受的,而服务器是读取本地资源,速度很快,所以没有影响。
AMD (了解)
- 定义: 异步加载模块
CMD (了解)
- 定义: 异步加载模块和CommnonJS的优点
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!