版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
了解模块化开于2013-6-12varvar_=$:function(id){ ementById(id); :function(key){... :function(key,value){...随着业务的发展,小A又编写了一系列的函数库和UI组件,比方说切换组以及ADtabs.jsbase.jsutil.js,他并没有添<script<script<script<script小的 的优化了小 { ementById(id);=function(key){...=function(key,value){... =require('base.js'),util=vardivtabs= 和,那也可以用varbase=require('base.js'),util=require('util.js');vardiv_tabs=base.$('tabs'); varbase=require('base.js'),ui=require('ui.js');vardiv_tabs=base.$('tabs'); 研究JavaScript模块化开发【精华汇DavidPadburyDavidPadbury写的《JavaScript模块化开发一瞥》正在考虑将模块(Modules)Harmony/ECMAScript6的语言级别功能。这多亏了模块系统编写者们的奇思妙aScript应用程序的语言。JavaScript不甚了解的开发者而言,他们最初必须要(patterns它们必将来自于语言本身实现之外。——RebeccaMurphyJavaScript不甚了解的开发者而言,他们最初必须要跑起来,不过很快代码就会变得一塌糊涂。而问题是,JavaScript没有为组织代码提供任何明显帮助。从字面上看,C#有using,Java(patterns它们必将来自于语言本身实现之外。——RebeccaMurphy模块模式(TheModulePatternBenCherry的帖子——JavaScriptModulePattern:In-Depth(深入理解JavaScript模块模式。1(function(lab49)2functionprivateAdder(n1,n2)returnn1+ 6lab49.add function(n1,n2)returnprivateAdder(n1, 11})(window.lab49=window.lab49||(ealuated的任何内容都是随处可用的。想象一下,要是先在lib1.js中了varname='...',然后又在lib2.js了varname='...'。那么后一句var就会替掉前一句的值——这可不太妙。然而,由于JavaScript拥有函数作用域级别,上例中所的一切都位于函数自身作命名空间window.lab49赋给其自身,要么将空对象{}赋给它。尽管看起来有点儿怪,不过让我们一起来看下这样一个虚构系统,系统中的那些js文件一律使用了上例中的函数包装器(functionwrapper。(...||...window.lab49目前已是对私有状态(Privatelab49window对象上,因此它是全局可用的。为了把其中的内容公布给模addlab49.add(22)add函数CommonJS(CommonJSCommonJSJavaScript运行库(server-sideJavaScriptruntimes)块系统并非标准,因为它不是出定JavaScript标准的同一社团,所以它更像是服务器端JavaScript运行库编写者彼此之间的非正式约定。我通常会支持CommonJS的想法,但要搞清楚的是:它并不是一份崇高而神圣的规(ES5一样;它只不过是一些人在邮件列表中所讨论的想法。而且多数想法都未付诸——RyanDahlnode.js全局变量exports供模块使用。而全局变量exports只是个普通的我通常会支持CommonJS的想法,但要搞清楚的是:它并不是一份崇高而神圣的规(ES5一样;它只不过是一些人在邮件列表中所讨论的想法。而且多数想法都未付诸——RyanDahlnode.js exports.add function(n1,n2)456 10varcalculator=require('./calculator');12calculator.add(2,Browserifyjsjs文件中,并把那些代码用生成的模块CommonJSJavaScript运行库设计的,而且由于有几个属性使得它们难以require必须立即返回——要是已经拥有所有内容时这会工作得很好,不过这导致难以使用加载器(scriptloader)去异步。每个模块占一个文件——CommonJS模块,必须把它们以某种风格组织异步模块定义(AsynchronousModuleDefini异步模块定义(AsynchronousModuleDefinition,通常称为AMD)已被设计为适合于浏览CommonJS社团的提案,不过自从迁移到上以后,现已加入了配套的测试套件,以便模块系统编写者来验证其代码是否符合AMD的API。AMD的是define函数。调用define函数最常见的方式是传入三个参数——模块名(也厂函数。(define函数的其他方式——AMDwiki。//calculator(计算器)define('calculator',['adder'],function(adder)returnadd:function(n1,n2) 78实际调用的是9*而且adder模块已一参数['adder']returnadder.add(n1,}define函数的调用中,因此这意味着可以欣然将多个模块都放在单jsdefine时,模块加载器已拥有控制权,因此为了与原先的CommonJS模块提案保持兼容已做出了巨大的努力。有些特殊行为是为了能在模块工厂函数中使用require及exportsCommonJS模块可直接拿JScurl.jsDojoAMDJavaScript应用程序,情JavaScript(DoesthismeanJavaScriptsucks?)我们已经能够随着JavaScript应用程序的发展进行迭代并改进。欲深入了解此请Tagneto的博客。10年前就已将此类功能引入语言。那么他们也不可能想到后来的那些需JavaScripttext(适合于构建现代JavaScript应用程序的语言。组织方式,本文试着对JavaScript模块化开发的一些基础知识做一些阐释。对象字面量(Object 对象字面量表示,其实就是用一对大括号括起来的键值对,也就是JavaScript对象的 }}functionKey:function()variableKey:varmyObject=654321varvarvariableName=21}}function}function876543立即执行函数(IIFEImmedia y-InvokedFunction当我们在类似于varname1=function(){…}这样的函数时,在后面加一对括号(),就可以让它立即执行,但是如果是functionname1(){…}这样的函数,则会有问function321上面代码在执行时会抛出错误,Unexpectedtoken(意外的标记),因为后面的()会被解1(function1(function(){/*code*/}223(function3(function(){/*code*/ 1varmyObject=2name:3getName:4return5}678 9myObject.getName();varmyObject=varname=returngetName:return}} myObject.getName();导入全局变varvarmyModule=(function(jQ)21})(jQuery}}function876543模块导varvarmyModule=(function()1returnmodule.publicMethod=function()}//varmodule={},privateVariable=扩展模myModule模块增加几个方法,通过前面的“立即执})(})(myModulereturnmy.xxMethod=function()varmyModule=(function(my)987654321myModulemyModule必须已经定义,如果扩展的xxMethod方法和myModule本身没有任何的依赖,那么要求myModule必须已经定义就毫无必要了,怎么解决这个问题呢,非常简单,只需要或一个//松//松散扩my.xxMethod=function()varmyModule=(function(my)43215 566778return8return99})(})(myModule||{} 了varmyModule=…,b.js中varmyModulea.jsb.js时,后者会将前者覆盖,这并不是我们期})(})(window.myModule=window.myModule||{}}my.xxMethod=function()(function(my)7654321JavaScript模块化开发的基础知识作了介绍,接下来,会进一步介绍常见的规范和 modules/JavaScript模块化开发(二)CommonJS规方式来加载,C#using,JavaScript本身没有内置的模块系统(ES6中引入了模块n年后的事情了,JavaScript的模块化规范,一般都是致力于提高JavaScript程序的可移植性和可交换性,朝着统一模块化交互方式的方向而努力。际上就是CommonJS的一个实现。CommonJSvarvarmath=132123exports.add=function()4varsum=0,i=0,args=arguments,l=5while(i<l)6sum+=7}8return9通过CommonJS的规范和代码可以看出,require是同步的,模块系统需要同步模块node.js,这一般来说没有问题,CommonJSServerJS,Modules1.0node.js上实践的很好,由于知道自了,在这个中,分出了AMD规范。由于风格和机制的差异,最终,AMDCommonJS社区中独立了出来,成为了现在最受 本条目发布于2013年9月26日。属于[01]前端开发分类,被贴了CommonJS、JavaScript。作者是Wayne.J。文章导→1.back通告:JavaScript模块化开发(四)——RequireJS|Feeldesign*3+三=您可以使用这些HTML和属性:<ahref=""title=""><abbr<acronymtitle=""><b><blockquotecite=""><cite><codeclass=""title=""data-url=""><deldatetime=""><em><i><qcite=""><strike><strong><preclass=""title=""data-url=""><spanclass=""title=""JavaScript模块化开发(三)AMD本文介绍一下AMD规范(AMDcpu的AMD可不是一回事)。AMD是“AsynchronousModuleDefinition”的缩写,意思就是“异步模块定义”。从名称上就AMD规范的API1过id才能知道从什么位置去加载依赖的模块)}returnmath.add(x,addTen:function(x)returndefine("adder",["math"],function(math)7654321如果这个模块并没有依赖,那么默认的依赖是["require"exportsmodule"],这时模块可returnx+exports.addTen=function(x)define("adder",function(require,exports)543211define(["math"],1define(["math"],function(math)2return2return3addTen3addTen:function(x)4return4returnmath.add(x,5}5}6677 一个和第二个参数,下面代码展示了这种用法,这也是CommonJS的写法,算是一种兼12345define(function(require,exports,module)vara= b=7exports.action=function() Dojo还有很多jsAMD规范,自己作为一个模块而存在,比如jQuery,MooTools等,所以AMD规范基本上已经是非常普及了,成为了事实上的标准。RhinoNode等环境。RequireJS遵循了AMD规范。本文主要说一说RequireJS的使用。获取和开始使用要充分使用RequireJS,在index.html文件中,应该把所有的内联都移除,只留下一<!DOCTYPE<!DOCTYPE12 2334<title>My4<title>MySample5<!--data-main5<!--data-main属性告require.jsrequire.js加载之后加js/main.js6677889<h1>My9<h1>MySample在main.js中,可以通过require()加载依赖 ,这样不用在html中显 main.js相当于是一个点12//scripts/helper/util.js加载完毕,会执行这个回调函3//如果util.js也了依赖的文件(模块),那么这个函数会等到那些依赖的文件(模块456js通过刚才的介绍,可以看出来RequireJS采用了不同于传统<script>的加载方式,传统的<script>方式一般都会有下面的代码:123456789 RequireJSRequireJSbaseUrldata-main了1的路径,在这句代码里也就是js文件夹;如果不data-main,则baseUrl默认指向这个html页面所在的文件夹。当然,也可以通过配置来baseUrl,下文会详述。注意,data-main中的模块会被异步加载,也就意味着如果页面后面通过<script>加载多个,这些不一定在data-main中的模块加载之后才加载;或者后面的js代码如果有对data-main中的模块的依赖,则有可能会出现错误。RequireJS会假定所有依赖项默认都是,所以书写依赖时可以省略“.js”后缀(path),我们也可以在配置中多个路径(paths),通过baseUrl+paths,可以用很少的代码找到相应的js文件,比起<script>要优雅简洁很多。一般来说,通过baseUrlpaths就可以找到js文件,不过有时候,可能会有例外,一旦RequireJS发现模块ID中包含如下的字符,那么它就不按照baseUrlpaths的方式来寻找这个模块的js文件了,而是采用URL的方式:ID“.js”ID以“/”ID“http:”“https:”一般来说,最好使用baseUrl+paths的方式来模块ID,这样做会有的灵活性。同样的,我们在组织js代码文件的时候,尽量避免使用很深的路径,而最好把js文件都放置在baseUrl下面,最好不要超过两层的深度,下面就是一个很好的例子:index.html1app.js//默认从js/lib中加载模baseUrl://如果模块ID以app开头,则会//不过要注意千万不要加上".12//默认js/lib中加载模3baseUrl:45 67paths:8app:9}function($,canvas,sub)//jQuerycanvasapp/sub模块都加载完毕后,会执行这个函使用RequireJSjQueryRequireJSjs文件只定义一个模块。不过这样的话,每加载一个模块,就会产生一个HTTP请求,RequireJS提供了一个优化工具,在最后生产环境中,可以打包所有模定义模块可以使用define()方法,define()有三个参数,可以参文中的介绍。sizesize:color:4321define(functiondefine(function()21334return5color:6size:7}81234define(["cart"],function(cart)returncolor:size:addToCart:function() 1define(["cart"],function(cart)2returnfunction(title)returntitle?(window.title=title):}3456的API可以参考说明RequireJSRequireJS采用head.appendChild()的方式来加载所有依赖的,这个方式的原理很varfilerefiffiletypejsjs文件载432156}7elseiffiletypecss"){//css文件载8varfileref=9}if(typeoffileref!=}RequireJS会顺着依赖链(也就是顺着模块的依赖层层进入,直到没有依赖为止)把加载非规范的模在加载没有实现AMD规范的模块(这种模块比实现了AMD规范的模块)时123//要使用shim来配置没AMD规范4//shim不能用来配置已经实AMD规范的模5shim:6'backbone':7//定义依赖backbone.js载入前载入这些依8deps:['underscore',9//exports:'underscore':exports:}}shim:deps:exports:'jquery.scroll':deps:exports:}}Sea.jsJavaScript模块加载框架。Sea.js的主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载,将前端工程师从繁重的JavaScript文件及对象依赖处理中解放出来,可以专注于代码本身的逻辑。Sea.js是国内比较流行的JavaScript模块加载框架,Sea.jsMIT协议,无论个人还Sea.jsJavaScriptCMD模块定义规范,定义规范。该规范明确详细信息,可以参阅Sea.jsLABjs是由KyleSimpson编写,用来管理JS执行的一个开源模块。下图是LABjs的分析图(转自携程UED)一些轻量级的可以使用Do,源码可以在这里找到。 20121026 块"(module)了。(正在制定中的ECMAScript 不是初级,但是只要稍稍了解Javascript的基本语法,就能看懂。}}上面的函数varmodule1=new_count:m1:functionm2:function} y-InvokedFunctionExpression,IIFE),可 varmodule1=var_count=varm1=varm2=m1:m1,m2: (module1._count);上面的代码为module1模块添加了一个新方法m3(),然后返回新的module1模})(jQuery,模块)当作参数输入module1。这样做除了保证模块的独立性,还使得模块之间 的讨论,参见BenCherry的著名文章Javascript模块化编程(二AMD20121030 的写法,我有我的写法,岂不是乱了套!考虑到Javascript模块现在还没有AMD,但是CommonJS2009年, 一个全局性方法require(),用于加载模块。假定有一个数学模块math.js,就可varmath=varmath=varmath=第二行math.add(2,3),在第一行require('math')之后运行,因此必须等完成,等待时间就是硬盘的时间。但是,对于浏览器,这却是一个大问题,因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。AMD是"AsynchronousModuleDefinition"的缩写,意思就是"异步模块定义"。AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参require([module],第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数math.add()与 模块加载不是同步的,浏览器不会发生假死。所以很显然AMD比较适合浏览器列的第三部分,将通过介绍require.js,进一步AMD的用法,以及如何将rqur.js2012117我采用的是一个非常流行的库require.js一、为什么要用js文件之间存在依赖关大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和都会变得。 性,只支持defer,所以把defer也写上。文件是main.js,也放在js <scriptsrc="js/require.js"data-data-mainjs下面js,所以可以把main.js简写成main。 像C语言的main()函数,所有代码都从这儿开始运行。下面就来看,怎么写main.jsalert("加载成他模块,这时就要使用AMD 规范定义的的require()函数。require(['moduleA','moduleB','moduleC'],function(moduleA,moduleB,require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是['moduleA','moduleB','moduleC'],即主模块依赖这三个模块;第二个参数require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它require.js会先加载jQuery、underscore和backbone,然后再运行回调函数。上一节最后的示例中,主模块的依赖模块是['jquery','underscore','backbone']。默认情况下,require.js假定这三个模块与main.js在同一个 为jquery.js,underscore.js 和backbone.js,然后自动加载。使用requir.config()
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年新能源行业存货质押贷款专项合同2篇
- 2025年度个人技术入股收益分配合同范本4篇
- 2025年度房地产项目融资担保借款合同样本4篇
- 二零二五年度门窗行业市场推广与宣传合同4篇
- 二零二五年智慧社区安防监控系统安装合同5篇
- 二零二五年度城市广场场地租赁合同2篇
- 2025年度全国棉花运输服务合同范本4篇
- 二零二五年外墙涂料翻新工程施工安全监管与隐患排查合同3篇
- 2025年度特种用途面包车租赁合同范本4篇
- 2025年度企业员工股票购买贷款合同终止后贷款处理协议
- 运动技能学习与控制课件第十一章运动技能的练习
- 虫洞书简全套8本
- 射频在疼痛治疗中的应用
- 四年级数学竖式计算100道文档
- “新零售”模式下生鲜电商的营销策略研究-以盒马鲜生为例
- 项痹病辨证施护
- 职业安全健康工作总结(2篇)
- 怀化市数字经济产业发展概况及未来投资可行性研究报告
- 07FD02 防空地下室电气设备安装
- 教师高中化学大单元教学培训心得体会
- 弹簧分离问题经典题目
评论
0/150
提交评论