持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
1. CommonJs【同步加载模块】
- 规范
- 一个文件就是一个模块,拥有单独的作用域
- 普通方式定义的变量、函数、对象属于该模块内;
- ++通过require来加载模块++
- ++通过module.exports或者exports来暴露模块中的内容++
- 注意
- 模块可以被多次加载,但是只是会在第一次运行的时候加载。然后运行结果就会被缓存了。以后的加载就直接读取缓存的结果
- 模块加载的顺序是按照代码出现的顺序同步加载的;
- __dirname代表当前模块所在的文件路径
- __filename代表当前模块文件所在的文件路径+文件名
- module.exports和exports的区别
- 打印这两者
console.log(exports)//输出:{} console.log(module);//输出:Module{...,exports:{},...}
module.exports和exports一开始都是一个空对象{},实际上,这两个对象指向同一块内存。 这也就是说module.exports和exports是等价的(有个前提:不去改变它们指向的内存地址) require引入的对象本质上是module.exports。 这就产生了一个问题,当 module.exports和exports指向的不是同一块内存时,exports的内容就会失效
```
# test.js
module.exports = {name:'小红'}
exports = {name:'小明'}
# main.js
let test=require('test.js')
console.log(test)//输出:{name:'小红'}
```
2. AMD【异步加载模块,浏览器端模块化的开发标准】【require.js】
- 规范
- 使用require.js来实现AMD规范的模块化
- 用require.config()指定引用路径
- 用define()来定义模块用require来加载模块 示例
# test.js # 语法:difine(id, dependencies, factory) # id:模块标识,可选参数; dependencies:是当前模块要用的模块名称组成的数组,可选参数 define('testModule',function(){ let name = 'test' return {name:name} }) # main.js require(['testModule'],function(t){ console.log(t);//输出:{name:'test'} }) - 特点
- 文件可以有依赖关系,被依赖的文件会早于依赖它的文件进行加载
- js加载的时候浏览器会停滞页面的渲染,加载文件越多,页面响应时间越长;【AMD异步加载解决了该问题】
- defer和async的相同和不同
- 都是异步加载【加载后续文档元素的过程将会和script.js的加载并行进行】
- 两者的执行时机不同,defer是在所有元素解析完成(DOMContentLoaded事件)之后【更符合预期】; async是加载完了就执行,应用于不考虑依赖关系的脚本更合适
- 文档的解析不会停止,其他线程将下载脚本
- 有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。
3. CMD 【sea.js】
- 规范
- 一个文件一个模块,用文件名作为模块id
- 示例
# test.js define(function(require,exports,module){ module.exports = {name:'test'} }) # main.js define(function(require,exports,module){ const t = require('test.js') export.name = t.name+',hi'; }) - 特点
- AMD和CMD的区别
- 不同点在于:AMD推崇依赖前置,提前执行,而CMD推崇依赖就近,延迟执行
- 和AMD类似
4. UMD
- 特点
- 整合了commonJs和AMD规范的方法
- 先判断是否支持Node.js的模块[export是不是存在],再判断是不是支持AMD【define是不是存在】
5.ES6Module
- 特点
- 浏览器和服务器通用的模块解决方案
- 注意
- export导出【文件内部的值变化后,再获取到的是最新值】
- export default导出的【文件内部的值变化后,再获取到的是初始值】
- 基本类型:无法在外部改变引入模块的值,因为是只读属性引入的
总结
require方式无法获取内部最新数据而且修改变量值会脱钩,
import方式外部无法修改模块的数据(只读),但是非默认导出属性可以获取内部最新值。