JS三教九流系列-require.js-网站模块化开发

js开发的模块化就是module处理

简单理解js模块化的开发就是让我们的web项目对js进行分类的处理

我们在开发网站的时候,里面会用要很多的类库,如jquery,还会有到基于jq各种插件,还会有其他类库,还有自己写的js或者jq代码等。一个html页面会有n多个script标签对外部js的引用,是不是感觉这样的页面会非常的混乱,如果我们可以只用一个script标签载入一个js文件,这个js文件把其他需要的js文件能全部加载进去,并且按着之间依赖关系执行,是不是一个页面就非常的整洁和容易扩展处理。

js的开发规范有AMD,典型代表就是require.js

CMD,典型代表就是sear.js

Commonjs规范我们已经接触过,在nodejs的安装和使用中我们在页面里运用require()请求原生模块、第三方模块和export定义我们第三方模块就是在运用commonjs的规范开发

我们的requirejs就是典型的amd规范处理,实现html页面中head.appendchild("script")的加载和内部依赖顺序处理

amd是异步加载模块化开发,采用异步的载入方式,也就是我们虽然先引用了require.js,下面的js文件也可能先执行处理,如果对上面有依赖,也可能失效。

我们通过参考requriejs的手册,去实践到我们的网页开发中去,利用amd模块化的技术去开发我们的网页。

requirejs文档地址 http://www.requirejs.cn/

requirejs下载地址 http://apps.bdimg.com/libs/require.js/2.1.11/require.min.js

咱们不去学习那么多的高级处理,基础功能已经足够我们的项目开发,一切为了开发去使用

下载requirejs,加载到html页面中,通过script标签的src属性加载require.js

<!DOCTYPE html>
<head>
<title>requirejs</title>
<meta charset="utf-8" />
</head>
<body>
<div class="aa">requirejs</div>
</body>
<script src="js/require.js" type="text/javascript"></script>
</html>

requirejs不使用多个script在html页面去加载所有js文件,通过require去做我们这种顺序加载处理

<script>标签含有一个特殊的属性data-main,require.js使用它来启动脚本加载过程

我们给页面添加data-main属性,指定我们的这个主要js控制加载的文件(都是对js的处理,所以省略了.js后缀)

<!DOCTYPE html>
<head>
<title>requirejs</title>
<meta charset="utf-8" />
</head>
<body>
<div class="aa">requirejs</div>
</body>
<script src="js/require.js" data-main="js/config.js" type="text/javascript"></script>
</html>

和我们的require的路径一样,都是放在了js这个文件下面,现在的目录

requ.html

js/reruire.js

js/config.js

我们已经知道,config.js就是我们的控制文件(文字自定义),在这里面我们定义和处理对其他文件的顺序加载

我们给config.js写入如下代码

requirejs.config({
  baseUrl: ‘js/modules/‘,
  paths: {
    jquery: ‘jquery‘
  }
});
require([‘jquery‘], function(jq) {
 
});

我们利用reruirejs的config方法去定义我们依赖的外部文件,

baseUrl属性:是定义外部文件加载的基本路径(比如我们的依赖js都在js/modules下)

paths属性:是定义加载外部文件的文件名,后缀.js省略(名字叫jquery.js,赋给指定键名jquery)

require方法:是请求加载我们的外部依赖文件,第一个参数是请求路径,这里就是jquery类库(目录js/modules/jquery.js),

jquery这个键值会自动拼接成 baseUrl+paths的路径进行加载

第二个参数是回调函数,里面的回调参数被赋值为请求的依赖文件

我们先看一下我们下载的目录结构:

requ.html

js/reruire.js

js/config.js

js/modules

js/modulesjquery.js

我们会把大量的外部放置在modules文件夹下面,html利用requirejs通过script加载外部文件,那么大量文件的基本目录就是:js/modules

我们浏览器打开html页面,firebug插件页面结构

我们的html页面其实只定义了require.js的引用,通过对config上面的设置,我们发现html页面已经加载了config.js和jqurey.js文件了!

config.js路径和data-mian的设置一样,

<script src="js/require.js" data-main="js/config.js" type="text/javascript"></script>

jquery.js的路径就是我们设置里面的baseUrl+paths

我们可以看出,我们config对路径的处理是站在html页面的角度去引用,如果站在config文件的角度去引用就错了,因为是给html页面去顺序加载js文件的

基本路径属性很好理解,就是相对html的路径,

文件属性的设置我们需要给他设置一个键名,键名的后面是引入文件的名字

require()方法:可以通过你的键名去请求加载外部文件的,看上面的path设置

我们通过config()定义了依赖文件

现在通过require()得到依赖,并且在回调函数中赋给了回调参数$

我们在回调函数内添加我们的jq处理代码,config.js修改如下

requirejs.config({ 
 baseUrl: ‘js/modules/‘,  
 paths: {    
  jquery: ‘jquery‘  
   }
});
require([‘jquery‘], function($) { 
 alert($(window).height());
 $("body").append("<div>append</div>")
});

页面弹出了窗口高度并且插入了div,我们利用requirejs加载jq类库,和基于jq的代码处理就完成了!!!

我们可以自己定义模块,用于依赖加载处理,

我们的依赖文件代码要放置在define()中。作为模块的定义,这样requirejs才可以加载依赖

我们创建自定义依赖文件,叫做ex.js(目录js/modules/ex.js)

modules创建ex.js,

define(function() {  
 var ex="我是依赖"
 return ex; 
});

config.js设置引入

requirejs.config({ 
 baseUrl: ‘js/modules/‘,  
 paths: {    
  jquery: ‘jquery‘,
  ex: ‘ex‘  
   }
});
require([‘jquery‘,"ex"], function($,ex) { 
 alert(ex)
 
});

我们浏览器打开HTML页面,会弹出“我是依赖”。

在js文件,我们将定义的内容反之在define里面,我们在config方法设置路径,require请求到,返回到到回调函数,我们回调函数的参数就会赋值为define里的内容

对于当前的ex.js文件就是在回调函数中 ex=function() {   var ex="我是依赖"; return ex; }

我们把ex的代码就行处理,不用原生js的处理代码,使用jq的代码,修改如下:

define(function() {  
 var ex=$(window).height();
 return ex;
});

审查报错了,因为你定义的模块不知道$是什么,define提供依赖的支持,我们修改如下:

define(["./jquery"],function($) {  
 var ex=$(window).height();
 return ex;
});

和require方法类似,可以先进行依赖请求,然后回调到回调参数中,这样定义的代码就对jq识别了,我们可以成功运行

我们看到,define加载依赖的路径是相对于当前js文件的,

我们既然在定义模块可以加载依赖,好了把ex.js修改为jq插件的形式,我们在以前文章写过jq的插件,我们以tab切换为案例

ex.js引入jq类库依赖,放入插件代码:

define(["./jquery"],function($) {  
 return $.fn.extend({
  tab:function(){ 
   return this.each(function () { 
    var obj = $(this);
    obj.find(".tabnav").children().click(function(){
  $(this).addClass("fou").siblings().removeClass("fou");
  $(this).parent().parent().find(".tabbox").children().eq($(this).index()).show().siblings().hide();
    });
   });
  }
 });
});

我们直接把插件的代码放入define里面就好了,我们的config.js代码引用插件

requirejs.config({ 
 baseUrl: ‘js/modules/‘,  
 paths: {    
  jquery: ‘jquery‘,
  ex: ‘ex‘  
   }
});
require([‘jquery‘,"ex"], function($,ex) { 
 $(".tab1").tab(); 
 
});

这时候ex回调参数其实没有什么意义,因为我们依赖是jq的插件,他会自动加上新的功能,我们html加上tab切换的html代码

<!DOCTYPE html>
<head>
<title>requirejs</title>
<meta charset="utf-8" />
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
/*demo*/
.tab1{height:400px; width:400px;}
.tabnav{height:50px; line-height:50px;}
.tabnav span{ cursor:pointer; margin:0 10px;}
.tabnav .fou{ color:#36F;}
.tabbox{height:350px; }
</style>
</head>
<body>
<div class="tab1">
    <div class="tabnav">
        <span class="fou">111</span>
        <span>222</span>
        <span>333</span>
    </div>
    <div class="tabbox">
        <div>111111</div>
        <div style="display:none;">22222222222</div>
        <div style="display:none;">33333333</div>
    </div>
</div> 
</body>
<script src="js/require.js" data-main="js/config.js" type="text/javascript"></script>
</html>

浏览器打开修改的页面,我们的tab效果成功执行了。

我们的插件里面放置了依赖,其实config里面可以放弃对jq类库的引用的

config修改如下

requirejs.config({ 
 baseUrl: ‘js/modules/‘,  
 paths: {    
  ex: ‘ex‘  
   }
});
require(["ex"], function(ex) { 
 $(".tab1").tab(); 
 
});

还是可以正确执行!插件里面加载了jq类库,当前没有加载!

我们如果在外部define定义模块加载了模块,那么我们这里引用外部文件会把define定义的代码和他的依赖都加载进去html页面

我们通过require加载的依赖,就是把整个js依赖放入在html中,我们config.js如下处理

requirejs.config({ 
 baseUrl: ‘js/modules/‘,  
 paths: {    
  jquery: ‘jquery‘  
   }
});
require(["jquery"], function() { 
 alert($(window).height())
 
});

我们的jq一样有效,请求到后,那么在回调内部就可以进行处理!

我们创建一个完整的项目,结构如下

requ.html   ?我们的静态页面

js/reruire.js    ?require文件

js/config.js     ?主要配置文件

js/modules    ?存放jq类库和插件文件的文件夹

js/modules/jquery.js    ? jq类库

js/handle/ys.js? 原生js文件,匿名函数返回消息

js/handle/ysfun.js ?原生js文件,匿名函数返回工具函数

html页面代码:

<!DOCTYPE html>
<head>
<title>requirejs</title>
<meta charset="utf-8" />
<style type="text/css">
/*reset*/
*{ padding:0; margin:0}
body{ height: 100%; width: 100%; font-size:12px; color:#333;}
/*demo*/
.tab1{height:400px; width:400px;}
.tabnav{height:50px; line-height:50px;}
.tabnav span{ cursor:pointer; margin:0 10px;}
.tabnav .fou{ color:#36F;}
.tabbox{height:350px; }
</style>
</head>
<body>
<div class="tab1">
    <div class="tabnav">
        <span class="fou">111</span>
        <span>222</span>
        <span>333</span>
    </div>
    <div class="tabbox">
        <div>111111</div>
        <div style="display:none;">22222222222</div>
        <div style="display:none;">33333333</div>
    </div>
</div> 
</body>
<script src="js/require.js" data-main="js/config.js" type="text/javascript"></script>
</html>

ex.js代码:

define(["./jquery"],function($) {  
 return $.fn.extend({
  tab:function(){ 
   return this.each(function () { 
    var obj = $(this);
    obj.find(".tabnav").children().click(function(){
  $(this).addClass("fou").siblings().removeClass("fou");
  $(this).parent().parent().find(".tabbox").children().eq($(this).index()).show().siblings().hide();
    });
   });
  }
 });
});

ys.js代码:

define(function() {  
 var ys="我是就是一个消息!";
 return ys;
});

ysfun.js代码:

define(function() {  
 var tools={};
 tools.norepeat=function(arr){
  arr.sort();
     var newarr=[];
     for(var i=0;i<arr.length;i++){  
   if(arr[i]==arr[i+1]){
   continue;
   }else{
   newarr.push(arr[i]);
   }
     };
  return newarr;
 };
 tools.strindex=function(str,arr){
  var index;
  for(var i=0;i<arr.length;i++){
   if(arr[i]==str){
    index=i;
   }
  };
  return index;
 };
 return tools;
});

config.js代码:

requirejs.config({ 
 baseUrl: ‘js‘,  
 paths: {    
  jquery: ‘modules/jquery‘,
  ex: ‘modules/ex‘, 
  ys: ‘handle/ys‘ ,
  ysfun: ‘handle/ysfun‘ 
   }
});
require(["jquery","ex","ys","ysfun"], function($,ex,ys,ysfun) { 
 $(".tab1").tab(); 
 alert(ys);
 var arr1=["123","44","55","66","789","44"];
 alert(ysfun.norepeat(arr1));
 alert(ysfun.strindex("66",arr1));
 
 
});

页面依赖jq类库,依赖jq的插件,还有其他js处理,一个基本页面的js引用大概就这些!

大概的实现:

  1. define定义模块,
  2. config设置依赖
  3. require请求加载依赖,回到参数可以接收依赖返回内容,回调函数内做进一步处理
  4. Commonjs规范在nodejs有体现,我们看看利用nodejs建站就知道了!
时间: 2024-08-30 08:31:07

JS三教九流系列-require.js-网站模块化开发的相关文章

JS三教九流系列-Zepto.js-为移动端开发的类库

zepto.js的api地址 http://www.css88.com/doc/zeptojs_api/ 类库源码下载http://www.zeptojs.cn/ 滚动当前页面,看到这部分点击下载 和使用jquery一样,我们只要html页面引入即可.zepto的api与jq几乎一样,同时各个接口名字也是一样的,我们只要按着写jq一样去写zepto就好了,既然这样,我们为何要用zepto,主要就是zepto提供时触摸事件,为开发移动端的更好处理. jq是为多个浏览器支持的类库,并没有封装上tou

Sea.js 提供简单、极致的模块化开发体验

http://seajs.org/docs/#intro 为什么使用 Sea.js ? Sea.js 追求简单.自然的代码书写和组织方式,具有以下核心特性: 简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码. 自然直观的代码组织方式:依赖的自动加载.配置的简洁清晰,可以让我们更多地享受编码的乐趣. Sea.js 还提供常用插件,非常有助于开发调试和性能优化,并具有丰富的可扩展接口. 兼容性 Sea.js 具备完善的测试用例,兼容所有主流浏览器:

JS三教九流系列-jquery实例开发到插件封装3

我们先写实例,然后可能需要在封装为插件,最后做更高级的处理! 封装插件基础学习 http://my.oschina.net/u/2352644/blog/487688 1-7实例地址  http://my.oschina.net/u/2352644/blog/490827 8-17实例地址 http://my.oschina.net/u/2352644/blog/491933 效果目录: 18.计数增加效果 19.模仿3d的焦点图效果 20.倒计时效果 21.导航滚动监听 18.计数增加效果 我

JS三教九流系列-jquery实例开发到插件封装

我们先写实例,然后在分装为插件,最后做更高级的处理! 封装插件基础学习 http://my.oschina.net/u/2352644/blog/487688 1.tab切换效果的实例和封装 tab切换效果的原理: 点击选项,对应内容项显示,获取选项索引,内容项索引等于选项索引的显示,其他内容项隐藏 要用的处理方法: $().index()获取当前对象的索引,从0开始 $().eq() 获取当前对象索引等于参数值的那一个  jq实例代码: <!DOCTYPE html PUBLIC "-/

JS三教九流系列-jquery实例开发到插件封装2

我们先写实例,然后有必要在分装为插件,最后做更高级的处理! 封装插件基础学习 http://my.oschina.net/u/2352644/blog/487688 前面的7个实例在这里 http://my.oschina.net/u/2352644/blog/490827 效果目录: 8.商品数量加减效果 9.星星评分效果 10.刮刮卡效果 11.圆形大转盘抽奖效果 12.贪食蛇小游戏效果 13.video的html5视频播放器 14.可拖拽的登陆框 15.树形菜单效果 16.全选/反全选处理

JS三教九流系列-jquery实例开发到插件封装4

我们先写实例,然后可能需要在封装为插件,最后做更高级的处理! 封装插件基础学习 http://my.oschina.net/u/2352644/blog/487688 1-7实例地址  http://my.oschina.net/u/2352644/blog/490827 8-17实例地址 http://my.oschina.net/u/2352644/blog/491933 18-23实例地址 http://my.oschina.net/u/2352644/blog/497003 效果目录:

2.精通前端系列技术之JavaScript模块化开发

在使用seajs模块化开发之前,直接在页面引用js会容易出现冲突及依赖相关的问题,具体问题如下 问题1:多人开发脚本的时候容易产生冲突(比如全局参数冲突,方法名冲突),可以使用命名空间降低冲突,不能完全避免冲突 // JavaScript Document /*var a = 10; function tab(){} function drag(){} function dialog(){}*/ var miaov = {}; //名字比较长 , 只能降低冲突,不能完全避免 miaov.a =

Sea.js提供简单、极致的模块化开发体验

为什么使用 Sea.js ? Sea.js 追求简单.自然的代码书写和组织方式,具有以下核心特性: 简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码. 自然直观的代码组织方式:依赖的自动加载.配置的简洁清晰,可以让我们更多地享受编码的乐趣. Sea.js 还提供常用插件,非常有助于开发调试和性能优化,并具有丰富的可扩展接口. 兼容性 Sea.js 具备完善的测试用例,兼容所有主流浏览器: Chrome 3+ ? Firefox 2+ ? Safa

(二)Node.js入门系列——Express.js安装

本篇文章讲express的安装与创建express项目. 一.安装express 执行命令 : npm install -g express; 安装express到npm-module,在express4.0之后,还需要安装express-generator 来完成express项目的创建, 执行命令 : npm install -g express-generator; 二.创建Express项目 然后就能够在目标路径下通过express命令创建项目.如需要在 D盘 的 project文件夹下