导图社区 js模块化
这是一篇关于js模块化的思维导图,主要内容有模块加载方案、前端模块化开发的价值、模块的循环引用。
这是一篇关于Codecademy - Javascript的思维导图,主要内容有Variables、Functions、lf statement、Switch statement、Loops等。
typescript语法的思维导图,主要内容有基本数据类型、对象类型、任意类型Any、联合类型Union Types、元组Tuple等。
社区模板帮助中心,点此进入>>
英语词性
互联网9大思维
组织架构-单商户商城webAPP 思维导图。
法理
刑法总则
【华政插班生】文学常识-先秦
【华政插班生】文学常识-秦汉
文学常识:魏晋南北朝
【华政插班生】文学常识-隋唐五代
【华政插班生】文学常识-两宋
模块化
模块加载方案
CommonJS
运用于nodeJS,适合服务端
var math = require('math');
服务器端同步加载模块,因为所有的模块都存放在本地硬盘,读取不是问题
CommonJS 模块输出的是一个值的拷贝
CommonJS 模块是运行时加载
因为 CommonJS 加载的是一个对象(即module.exports属性),此对象要在脚本运行完才能生成
AMD
应用于requireJs(、curl.js)
require([module], callback); module要加载的模块数组,callback:加载成功之后的回调函数
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
依赖前置,js可以方便知道依赖模块是谁,立即加载
浏览器端,需要异步加载
一开始就把所有依赖写出来,但不符合书写的逻辑顺序
运行时 才能确定,模块的依赖关系,以及输入和输出的变量
CMD
是seajs推崇的规范
通过 exports 暴露接口。这意味着不需要命名空间了,更不需要全局变量。这是一种彻底的命名冲突解决方案。
通过 require 引入依赖。这可以让依赖内置,开发者只需关心当前模块的依赖,其他事情 Sea.js 都会自动处理好。对模块开发者来说,这是一种很好的 关注度分离,能让程序员更多地享受编码的乐趣
就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块(牺牲性能来带来开发的便利性)
依赖就近,用的时候再require
UMD (通用模块依赖)
兼容方案,根据内容来判断选择 AMD 还是 CommonJS.
ES6 Module
1. ES6 模块输出的是值的引用
原理:js引擎对脚本做静态分析的时候,遇到模块加载命令import ,就只会生成一个只读引用。等到脚本工具真正执行时,再根据这个只读引用,到被加载的模块中去取值,(类似于Linux的符号连接)原始值变了,import加载的值也会动态改变
原理2:export通过接口,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例
2. ES6 模块是编译时输出接口
原理:ES6模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成(import时不会执行模块,只是生成一个指向被加载模块的引用,需要开发者自己保证真正取值时能够取到值)
浏览器加载方式:浏览器对于带有type="module"的<script>,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本。等同于打开了script标签的defer属性
尽量的静态化,使得 编译时 就能确定模块的依赖关系,以及输入和输出的变量。
前端模块化开发的价值
恼人的命名冲突
烦琐的文件依赖
模块的循环引用
结果:一旦出现某个模块被循环加载,就只输出已经执行的部分,还未执行的不会输出
加载原理
require命令第一次加载该脚本就会执行整个文件,在内存中生成 包括模块名id,模块输出接口exports,模块脚本是否执行完毕loaded 等属性的 对象.
以后要用到这个模块时,就会到exports属性上取值。即使再次执行require命令,也不会再次执行该模块,而是到 缓存 中取值。
ES6
结果:只要引用是存在的,代码就能执行
es6模块是动态引用,遇到import时,不会去执行模块,而是生成一个指向被加载模块的引用
用到这个模块时,只要引用是存在的,代码就能执行