宝哥软件园

详细解释JavaScript模块化开发

编辑:宝哥软件园 来源:互联网 时间:2021-09-07

什么是模块化开发?

在前端开发中,最初在脚本标签中嵌入几十上百行代码就可以实现一些基本的交互效果。后来,js得到了重视和广泛应用。借助jQuery、Ajax、Node。Js、MVC、MVVM等。前端开发也受到重视,前端项目也越来越复杂。然而,JavaScript并没有为组织代码提供任何明显的帮助,甚至没有类的概念,更不用说模块了。

模块是实现特定功能的文件。有了模块,我们可以更方便地使用别人的代码,如果我们想要任何功能,可以加载任何模块。模块开发需要遵循一定的规范,否则会混淆。

根据AMD规范,我们可以使用define定义模块,使用require调用模块。

目前流行的js模块规范有两种:CommonJS和AMD。

AMD规格

AMD是异步模块定义,中文名字的意思是“异步模块定义”。它是浏览器端模块化开发的规范,服务器端的规范是CommonJS

模块将异步加载,模块加载不会影响以下语句的运行。所有依赖于某些模块的语句都放在回调函数中。

AMD是RequireJS提升过程中模块定义标准化的产物。

定义()函数

AMD规范只定义了一个函数define,它是一个全局变量。该功能描述如下:

定义(id?依赖性?工厂);参数描述:

Id:指定含义中模块的名称,可选;如果未提供此参数,模块的名称应该默认为模块加载程序请求的指定脚本的名称。如果提供了此参数,模块名称必须是“顶级”和绝对的(不允许使用相对名称)。

依赖项:它是当前模块所依赖的数组文字,并且已经由模块定义的模块标识。从属参数是可选的。如果忽略此参数,它应该默认为['require ',' exports ',' module']。但是,如果factory方法的length属性小于3,加载程序将选择使用函数length属性指定的参数数量调用factory方法。

工厂方法工厂,模块初始化要执行的函数或对象。如果是函数,应该只执行一次。如果是对象,这个对象应该是模块的输出值。

模块名称的格式

模块名称用于唯一标识定义中的模块,它们也用于依赖数组:

模块名是由正斜杠分隔的一串有意义的单词。单词必须是驼峰形式,或“.”,' .'模块名不允许文件扩展名的形式。例如,“。js "模块名称可以是“相对”或“顶级”。如果第一个字符是“.”或“.”,它是相对模块名顶层的模块名。从根命名空间的概念模块中解析相对模块名。解析从“require”写入和调用的模块

使用需求和导出

创建一个名为“alpha”的模块,使用require、exports和名为“beta”的模块:

define('alpha ',['require ',' exports ',' beta '),function (require,exports,beta){ exports . verb=function(){ return beta . verb();//Or:要求返回(' beta ')。动词();} });必需原料药简介:https://github.com/amdjs/amdjs-api/wiki/require

AMD规范中文版:https://github.com/AMD js/AMD js-API/wiki/AMD-(中文版)

目前实现AMD的库有RequireJS、curl、Dojo、结节等。

CommonJS规范

CommonJS是服务器端模块的规范,Node.js采用了这个规范。节点。js首先采用了JS模块化的概念。

根据CommonJS规范,单个文件就是一个模块。每个模块都是一个独立的作用域,也就是说,模块中定义的变量不能被其他模块读取,除非它们被定义为全局对象的属性。

输出模块变量的最好方法是使用module.exports对象。

var I=1;var max=30module . exports=function(){ for(I-=1;我最大;){ console . log(I);} max *=1.1};上面的代码通过module.exports对象定义了一个函数,它是模块外部和内部通信的桥梁。

load模块使用require方法,该方法读取一个文件并执行它,最后返回该模块。

通用规范:http://javascript.ruanyifeng.com/nodejs/commonjs.html

RequireJS和SeaJS

RequireJS由詹姆斯伯克创建,他也是AMD规范的创始人。

define方法用于定义模块,RequireJS要求将每个模块放在单独的文件中。

RequireJS和Sea.js都是模块加载器,提倡模块化开发的概念。核心价值是让JavaScript的模块化开发变得简单自然。

SeaJS和requires js最大的区别是:

SeaJS对模块的态度是懒执行,而RequireJS对模块的态度是预执行。

不明白?看看这篇图文并茂的文章:http://www.douban.com/note/283566440/

API:http://www.requirejs.cn/docs/api.html要求

需求的用法:http://www.ruanyifeng.com/blog/2012/11/require_js.html

为什么使用requireJS

想象一下,如果一个网页有很多js文件,浏览器在下载网页时会先加载js文件,从而停止网页的渲染。如果有更多的文件,浏览器可能会失去响应。其次,为了保证js文件的依赖性,最依赖的模块(文件)应该最后加载。当依赖关系复杂时,编写和维护代码将变得困难。

RequireJS的诞生就是为了解决这两个问题:

(1)实现js文件的异步加载,避免网页失去响应;(2)管理模块之间的依赖关系,方便代码编写和维护。

所需文件下载:http://www.requirejs.cn/docs/download.html

AMD和CMD

通用模块定义是一个通用的模块定义。本规范定义了模块的基本编写格式和基本交互规则。该标准是在中国制定的。AMD是依赖前端,CMD是按需加载。

在CMD规范中,模块是一个文件。代码编写格式如下:

定义(工厂);当工厂是一个函数时,它表示模块的构造方法。通过执行该构建方法,可以获得模块提供的接口。执行factory方法时,默认情况下会传入三个参数:require、exports和module:

定义(函数(要求、导出、模块){//模块代码});Require是可以导入其他模块的参数,而export可以导出模块中的一些属性和方法。

CMD规格地址:https://github.com/seajs/seajs/issues/242

AMD是RequireJS推广过程中模块定义的标准化输出。CMD是SeaJS推广过程中模块定义的标准化输出。

对于依赖模块,AMD提前执行,CMD延迟执行。

AMD:提前执行(异步加载:依赖关系优先执行),CMD:延迟执行(运行到需要加载为止,按照顺序执行)。CMD主张依靠邻近,AMD主张依靠优先。请看下面的代码:

//CMDdefine(函数(需要,导出,模块){var a=require('。/a') a .做某事()//100行var b=require('。/b ')在这里省略//你可以写b . dosomesing()//.})//AMD建议默认定义(['./b'],函数(a,b) {//依赖关系必须写成a . dosometing()//100行b.doSomething().}在此省略。另一个区别是:

AMD:api根据其应用范围不同而不同,但使用相同的api接口CMD:每个API都有一个单一的职责。AMD具有异步并行加载的优势。在AMD的规范下,异步加载不会同时产生错误。CMD的机制不同。这种加载方法会产生错误。如果可以标准化模块的内容形式,还可以

Jquery1.7及以上将自动模块化,支持AMD模式:主要使用define功能。虽然sea.js是CommonJS规范,但是define是用来定义模块的,所以jQuery已经被自动模块化了

Seajs.config ({'base' :'/',' alias ' : { ' jQuery ' : ' jQuery . js '//define jQuery file } });定义功能类似于AMD的定义:

Define (function (require,exports,module){//首先加载jQuery var $=require('jquery ')的模块;//然后将jQuery对象传递给插件模块require('。/cookie ')($);//开始使用$。cookie方法});如何使用sea.js?

介绍sea.js的库

如何成为模块?

规定

3.如何调用模块?

-exports-sea.js.use4 .如何依赖模块?

-要求

脚本类型='text/javascript' define(函数(必需,导出,模块){//导出:对外的接口//需要:依赖的接口要求('。/test。js’);//如果地址是一个模块的话,那么需要的返回值就是模块中的exports })/scriptsea.js开发实例

!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN ' ' http://www .w3。org/TR/XHTML 1/DTD/XHTML 1-Transitional。DTD ' html xmlns=' http://www .w3。org/1999/XHTML ' hearteta http-equiv=' Content-Type ' Content=' text/html;charset=utf-8' /title鼠标拖拽的模块化开发实践/title style type=' text/CSS ' # div 1 { width :200 px;高度:200 px背景:黑色;位置:绝对;display : none } # div 2 { width :30 px高度:30 px背景:黄色;位置:绝对;底部:0;right :0 } # div 3 { width :100 px高度:100 px背景:蓝色;位置:绝对;right:0top:0}/style脚本类型=' text/JavaScript ' src=' http :/海。js '/脚本脚本类型=' text/JavaScript '/A同事:seajs.use(' ./main。js’);/script/head dyinput type=' button ' value='确定id='输入1 '/div id=' div 1 ' div id=' div 2 '/div/div id=' div 3 '/div/body/HTMl同事

//A同事写的main.js:define(函数(必需,导出,模块){ var oInput=document。getelementbyid('输入1 ');var ODI v1=文档。getelementbyid(' div 1 ');var ODI v2=文档。getelementbyid(' div 2 ');var ODI v3=文档。getelementbyid(' div 3 ');要求('。/drag.js ').拖动(ODI v3);哼哼。onclick=function(){ ODI v1。风格。display=' block要求('。/scale.js ').刻度(oDiv1、ODI v2);require.async(' ./scale.js ',函数(ex) { ex.scale(oDiv1,ODI v2);}) }});B同事

//B同事写的拖拉。js : define(function(require,exports,module){ function drag(obj){ var DIsX=0;var DIsy=0;物体。onmousedown=function(ev){ var ev=ev | | window。事件;disX=ev。clientx-obj。offsetleftdisY=ev。客户-对象。偏移;文件。onmousemove=function(ev){ var ev=ev | | window。事件;var L=必需' ./range.js ').范围(ev.clientX - disX,文档。文档元素。客户端宽度-obj。offsetwithts,0);var T=必需' ./range.js ').范围(ev.clientY - disY,document。文档元素。客户端高度-obj。偏右,0);物体。风格。左=L ' px物体。风格。top=T ' px};文件。onmouseup=function(){ document。onmousemove=nulldocument . onmouseup=null };返回false };} exports.drag=drag//对外提供接口});C同事

//C同事写的规模。js : define(function(require,exports,module){ function scale(obj1,obj 2){ var DIsX=0;var DIsy=0;var DIsw=0;var DisH=0;obj 2。onmousedown=function(ev){ var ev=ev | | window。事件;disX=ev . clientxdisy=ev . clientydisw=obj 1。用.抵消;disH=obj 1。偏移光线;文件。onmousemove=function(ev){ var ev=ev | | window。事件;var W=必需('。/range.js ').范围(ev.clientX - disX disW,500,100);var H=必选('。/range.js ').范围(ev.clientY - disY disH,500,100);目标1。风格。宽度=W ' px目标1。风格。高度=H ' px};文件。onmouseup=function(){ document。onmousemove=nulldocument . onmouseup=null };返回false };} exports . scale=scale });D同事

//D同事的range.js -限定拖拽范围define(function(require,exports,module){ function range(iNum,iMax,IMin){ if(InUM IMAx){ return IMAx;} else if(InUM IMin){ return IMin;} else { return InUM } } exports . range=range });

requirejs开发实例

require.config用于定义别名,别名是在paths属性下配置的。然后传递requirejs(参数一,参数二);第一个参数是数组,传入我们需要引用的模块名,第二个参数是回调函数,传入一个变量,而不是刚才介绍的模块。

main.js文件

//别名配置需要js . config({ path : { jquery : ' jquery . min '//)。js }}可以省略);//引入模块,用变量$表示jquery模块requirejs (['jquery'],function ($) {$ ('body ')。CSS('背景色','红色');});入门模块也只能写require()。Requirejs通过define()定义模块,定义的参数是相同的。此模块中的方法和变量不能在外部访问,只能通过return返回。

定义模块

定义(['jQuery'],函数($){//引入jQuery模块返回{add:函数(x,y){ return x y;} };});通过将其命名为math.js来保存模块

Main.js引入模块方法

需要(['jquery ',' math'],函数($,math) { console.log(math.add(10,100));//110});没有依赖性

如果定义的模块不依赖于其他模块,您可以:

define(function(){ return { name : ' trig kit 4 ',age : ' 21 ' } });AMD推荐的风格是将对象作为模块对象返回,而CommonJS的风格是通过为module.exports或exports的属性赋值来公开模块对象。

更多资讯
游戏推荐
更多+