引入问题:为什么要进行模块化?
1)模块化就是将系统分离成独立功能的模块,这样我们需要什么功能,就加载什么功能
telegram的的官网的最新的下载是多少
2)模块化的好处:
避免命名空间的冲突(减少命名空间的污染)更好的分离,实现按需加载提高可代码的复用性提高了代码的维护性
JS模块化大致发展过程
CommonJS(服telegram官网的最新下载的网站在哪里务端)=》AMD(浏览器)=》CMD=》ES6 Module模块化
模块化规范的种类telegram的官网的最新下载网址在哪呢
telegram 的中文是多少
模块化规范的发展趋势
终极:现代工具webpack
webpack自己实现了一套模块机制,无论是CommonJs模块的require语法还是ES6模块的import语法,都能够被解析并转换成指定的环境的可运行代码。(随着webpack打包工具的流行,ES6语法广泛手中,后来开发者对于AMD CMD的感知越来越少)
1.CommonJS规范
1.1说明:
每个文件都可以作为一个模块(这里的文件指的是js文件)在服务器端:模块的加载是运行时同步加载的在浏览去端:模块需要提前编译打包处理,不然浏览器不能识别require语法
1.2 使用
主要分为定义模块和引入模块两个步骤
定义模块语法:
引入模块语法
模块标识:
模块标识就是require()函数的参数,规范是这样的:
必须时字符串可以时以https://blog.csdn.net/weixin_46872121/article/details/ telegram的的官网的最新下载方法是什么 …/开头的相对路径可以时绝对路径可以省略后缀名
其中,当引入的模块为自定义的模块时,那么url则是该模块所在的路径
当引入的模块是第三方模块时,则url为其具体包名
标准内容:
模块通过来向外暴露API,只能是一个对象,暴露的API需作为此对象的属性定义全局函数,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴露出来的API如果被reqiure函数引入的模块中也包含依赖,那么以此加载这些依赖
特点
模块加载是一项阻塞操作,也就是同步加载
1.2.1模块定义与使用
举例1:
方式①(module1.js)
方式②(module2.js)
方式③(module3.js)
引入(一般在主模块中如main.js)
举例2:
举例3:
2.AMD规范
2.1说明
CommonJS规范出现后,在Node开发中产生了非常好的效果,开发者希望借鉴这个经验来解决浏览器JS的模块化但是大部分人认为浏览器和服务器的环境差别太大,毕竟浏览器JS时通过网络动态以此加载的,而服务器的JS是保存在本地磁盘中。因此浏览器需要实现异步加载,模块在定义的时候就必须先知名它所需要依赖的模块,然后把本模块的代码写在回调函数中执行,最终衍生出了AMD规范AMD的主要思想时异步模块,主逻辑在函数回调中执行
2.2 telegram的中文下载地址怎么找 标准内容
1.定义没有依赖的模块
module1.js
2.定义具有依赖的模块
module2.js
3.引入模块
main.js
2.3 举例使用:
人无完人,AMD/RequireJS 也存在饱受诟病的缺点。按照 AMD 的规范,在定义模块的时候需要把所有依赖模块都罗列一遍,而且在使用时还需要在 factory 中作为形参传进去。
CMD/RequireJS模块化的顺序是这样的:
所以是依赖加载完成后会先预先将模块执行一遍,这种方式会使得程序效率低;
3.CMD规范
3.1 说明
AMD/RequireJS的JS模块实现有很多不优雅的地方,主要原因不能以一种更好的管理模块的依赖加载和执行;
那么就出现了SeaJS,SeaJs遵循的是CMD规范,CMD规范在AMD的基础上改进的一种规范,解决了AMD对依赖模块的执行时机的问题;SeaJS模块化的顺序是:SeaJS的用法和AMD基本相同,并且融合了
CommonJS的写法:
3.2 使用
(对于模块的引入,具有同步和异步两中方式)
总结:
SeaJS的出现,是CommonJS在浏览器的践行者,并吸收了RequireJS的优点
4. ES6中的Module模块
4.1 标准内容
模块功能主要由两个命令构成:和用于暴露接口,用于引入模块
4.2 模块的定义
有如下3中方式
方式1—–分别暴露
方式2—统一暴露
方式3—-默认暴露
4.4 模块的引入
在使用 ES Module 值得注意的是:import 和 export 命令只能在模块的顶层,在代码块中将会报错,这是因为 ES Module 需要在编译时期进行模块静态优化,import 和 export 命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行,这种设计有利于编译器提高效率,但也导致无法在运行时加载模块(动态加载)。
对于这个缺点,TC39 有了一个新的提案 – Dynamic Import,提案的内容是建议引入 方法,实现模块动态加载。
import()方法返回一个Promise对象
PS:
函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。
它是运行时执行,也就是说,什么时候运行到这句话,就会加载到指定的模块。另外,函数所加载的模块没有静态链接关系,这点也是与语法不同注意的时ES6 的Module语法有些浏览器是不支持的,因此需要Babel先进性转码,将import和export命令转成ES5语法才能被浏览器解析。
这里举例之前做过的一个小项目,就是使用了ES6语法中的module模块化思想结合axios库,将需要向服务端发送请求的操作封装到一个模块中,然后对于不同的请求数据操作,直接导入该模块调用即可
1)封装ajax请求函数(使用的时默认暴露)
2)封装接口请求函数—-使用的时分别暴露
(这个接口函数需要导入上面封装的ajax请求函数,调用,发送请求)
3)当其他模块需要调用发送请求时,直接使用import结构导入封装的接口函数即可
5.CommonJS、AMD、CMD、ES6 Module的区别
5.1 AMD与CMD区别
1)模块定义时对依赖的处理不同
AMD推崇迁至以来,在定义模块时就要声明其依赖的模块;而CMD推从就近依赖,只有在用到某个模块时再使用require导入;
AMD:
CMD:
2)对依赖模块的处理机制不同
首先AMD和CMD对模块的加载方式都是异步的不过区别在于AMD当加载了依赖模块之后立即执行依赖模块,依赖模块的执行顺序和我们书写的顺序不一定一致;而CMD加载完依赖模块之后,并不会立即执行,等所有的依赖模块都加载好之后,进入回到函数逻辑,遇到require语句的时候,才执行对应的模块,这样模块的执行顺序就和我们书写的时候一致了
5.2 ES6模块与CommonJS模块加载的区别
CommonJS时运行时加载,因为ComminJS加载是先加载整个模块,生成一个对象(这个对象包含了path这个模块的所有API),然后再从这个对象上面读取方法—–运行时加载ES6是编译时加载,ES6模块不是对象,它的对外接口只是一种静态定义,在代码静态定义阶段就会生成—–编译时加载
以上这种写法与CommonJS的模块加载有什么不同?
当require path 时,CommonJS会将path模块运行一遍,并返回一个对象,这个对象包含path模块的所有API。
参考文章:
https://juejin.cn/post/6844903629447495687