前言前端的模块化之路经历了漫长的过程。想深入了解的可以看看浪中航行大师写的前端模块化详解(完整版),根据几位大佬写的文章,这里总结整理一下模块化规范部分。希望看过的小伙伴能够有所收获,也希望觉得有用的小伙伴点个赞,补充一下。什么是模块?一个复杂的程序,按照一定的规则(标准)封装成若干个块(文件),组合在一起。块的内部数据和实现都是私有的,只对外暴露一些接口(方法)。与其他模块的通信CommonJSNode应用程序由模块组成,采用CommonJS模块规范。每个文件都是一个模块,有自己的作用域。文件中定义的变量、函数和类都是私有的,对其他文件不可见。在服务器端,模块在运行时同步加载;在浏览器端,模块需要提前编译打包。CommonJS规范的加载模块是同步的,也就是说加载完成后才能进行后面的操作。基本语法:exposemodule:module.exports=valueorexports.xxx=valueimportmodule:require(xxx),如果是第三方模块,xxx是模块名;如果是自定义模块,xxx是模块文件路径但是,CommonJs有一个明显的局限性使其不适合浏览器环境,那就是require操作是同步的。这在服务器端是没有问题的,因为所有的模块都存储在本地硬盘中,可以同步加载,等待的时间就是硬盘的读取时间。但是,对于浏览器来说,这是一个很大的问题,因为模块是放在服务器端的,等待时间取决于网速,可能需要很长时间,浏览器处于“假死”状态.因此,浏览器端的模块不能使用“同步加载”(synchronous),只能使用“异步加载”(asynchronous),这也是AMD规范诞生的背景。AMD特性:异步加载模块,允许指定回调函数,浏览器一般使用AMD规范代表作:require.jsusage://definemoduleswithoutdependenciesdefine(function(){returnmodule})//definedependenciesModuledefine(['module1','module2'],function(m1,m2){returnmodule})//引入和使用模块require(['module1','module2'],function(m1,m2){//使用m1/m2})CMD特点:专用于浏览器端,模块的加载是异步的,在使用模块时会加载并执行模块。exports,module){exports.xxx=valuemodule.exports=value})//定义依赖模块define(function(require,exports,module){//引入依赖模块(同步)varmodule2=require('./module2')//引入依赖模块(异步)require.async('./module3',function(m3){})//暴露模块exports.xxx=value})//引入并使用模块define(function(require){varm1=require('./module1')varm4=require('./module4')m1.show()m4.show()})CMD和AMD的区别AMD和CMD最大的区别就是dependencymodule执行时机的处理不同,不是加载的时机或方法。两者都是异步加载模块。AMD依赖前端,js可以轻松知道依赖的模块是谁,并立即加载;而CMD依赖最近的,需要用模块解析成字符串才能知道依赖了哪些模块。这也是很多人诟病CMD的一点,牺牲性能来带来开发的方便,其实解析模块使用的时间短到可以忽略不计。一句话总结:两者都是异步加载,只是执行的时机不同。AMD靠前端,提前执行,而CMD靠就近,延迟执行。UMDUMD是AMD和CommonJS的结合:AMD模块采用浏览器优先原则开发,模块异步加载。CommonJS模块基于服务器优先原则开发,选择同步加载,其模块不需要打包(unwrappedmodules)。这就迫使人们想出另一种更通用的模型UMD(UniversalModuleDefinition)。希望有一个跨平台的解决方案。UMD首先判断支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。在判断是否支持AMD时(define是否存在),存在则使用AMD方式加载模块。(function(window,factory){if(typeofexports==='object'){module.exports=factory();}elseif(typeofdefine==='function'&&define.amd){define(factory);}else{window.eventUtil=factory();}})(this,function(){//module...});ES6模块化ES6模块被设计成尽可能静态的,这样在编译时可以确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块都只能在运行时确定这些东西。例如,CommonJS模块是对象,必须在输入时查找对象属性。ES6Module浏览器默认还不支持,需要用babel,每天写demo时经常出现这个错误:ES6modules使用import关键字导入模块,export关键字导出模块:/**导出模块的方式**/vara=0;export{a};//第一类exportconstb=1;//第二种letc=2;exportdefault{c}//第三种letd=2;exportdefault{dase}//第四种,别名/**导入模块的方式**/import{a}from'./a.js'//export导出方式,.js后缀可以省略importmainfrom'./c'//export默认导出方式,使用main.cimport'lodash'//只执行lodash模块,不输入任何值namedexport和defaultexportexport{
