您的位置:首页 > 产品设计 > UI/UE

require.js的结构及常用组件用法

2017-04-21 13:42 525 查看
 
require.js适用于包含多个js文件的复杂单页面应用。只要单个页面的js文件超过了一定的数量且相互间有依赖关系,并且项目中用到了模块化开发,就适合使用require.js。如果js文件不超过5个还是不必要使用require.js而直接引用就行。requireJs主要体现了一种模块化的编程思想,而你只需要按照requireJs的规范进行开发,就能将功能模块化,熟悉之后也能感受到模块化编程带来的好处:依赖清晰,模块分离,扩展维护方便,通过按需加载让页面加载更流畅。

本文转自:前端网原文
我无法将requireJs的API讲解的更好,这里我从requireJs在项目中的实际应用,我会从下面几点依次讲解和介绍:
1,目录结构
2,页面结构
3,配置requireJs
4,模块的加载
5,requireJs的模板组件(text.js)压缩组件(r.js)
6,mustache.js的和requireJs的组合应用

Require.js的目录结构:

     requireJs与普通的通过<script>标签直接引入的方式不同,它管理着所有js文件的引用依赖和加载,所以在页面上只需要通过一个<script>标签引入require.js的主文件,requireJs要求必须在这个标签上增加一个特殊的“data-main”属性。这个属性指定requireJs的配置文件,即指定大众组件(比如jquery.js,bootstrap.js,mustache.js)的路径并赋予moduleID(模块ID),然后初始化用户界面(比如动态渲染首页数据);moduleID是每个模块(每个js文件)对应路径的“缩写”,也就是说,requireJs用一个变量保存或者寻找相应文件模块的路径,需要使用时只需要使用该moduleID即对应变量,比如:待会儿的配置中“jqueryID”:"/thirdLib/jqueryJs/jquery.min",其中,前面的“jqueryID”是模块ID,后面则是jquery文件的路径,后面引用jquery的时候则只需要使用jqueryID便引用了jquery。在这种情况下,我们的目录结构应尽量扁平化(文件夹层级不要太深,所有js文件应放到同一个相对路径下,分类清晰。不止requireJs,所有类型的项目都应有一个简洁且分类明确的目录结构。)。

下面直接上结构图示例:

(每根红线连接至对应的介绍,可以看一下整个示例的结构及各个组件的大致功能。)



      可以看到,整个结构是按照:css
,html ,js ,index.html来分的,这样的好处是:相对于,index.html来说,每个文件都能直接向下寻找,不用“../../”这样有着复杂而多级的嵌套。所有js文件也能以“./js为根路径(baseUrl)”

Require.js的引入方式:

这是index.html中的具体代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MAINFRAME</title>
</head>
<body>
<h1>Hello RequireJs</h1>
<div id="context"></div>
<script type="text/javascript" src='./js/thirdLib/requirejs/require.js' data-main='./js/mainFrame.js' charset="utf-8"></script>
// 使用require.js的应用只需在页面中引入require.js主体文件,并在该<script>标签中添加data-main属性并设置配置文件的路径,到这一步
// 后面指定js文件路径时都可以忽略“.js”后缀了,因为requireJs默认会加上.js后缀,所以你再加一次的话会导致文件名不对,而无法加载。
</body>
</html>



Require.js的配置:
接着看一下mainFrame,js的代码,具体细节会在代码注释中详细讲解:

//定义一个require的配置方法,
var requireConfig={
baseUrl: 'js/', //这里指定requireJs加载js文件的根路径,它是相对于引用require.js的html页面来定的,
//比如我们现在的示例中是index.html引用了require.js,
//所以这个“js/”路径是相对于index.html的。
paths : {
text:'thirdLib/requirejs/text', //模板加载引擎,前面的“text”是moduleID,这里指定了路径,后面调用时只需用“text”这个ID,
mustache:'thirdLib/mustache.min', //模板渲染引擎,渲染html模板中并返回带内容的元素节点,再添加到页面中。
jquery:'thirdLib/jqueryjs/jquery-2.1.4', //jquery.js
bootstrap:'thirdLib/jqueryjs/bootstrap.min', //bootstrap.min.js
backbone:'thirdLib/backbonejs/backbone', //backboue.js
underscore:'thirdLib/backbonejs/underscore' //underscore
//需要说明的是:这里所有的配置只是为一些常用组件指定moduleID,
//书写的顺序不影响它们之间的倚赖关系。bootstrap写在jquery的前面也没有问题。
//路径都需要忽略“.js”后缀,否则无法加载。
},
shim : { //配置js文件间的倚赖关系。
bootstrap:{ //这里的模块ID 是上面paths配置中定义moduleID,我试了一下不论是否用引号包起来都有用。
deps:['jquery'] //这里的意思是:bootstrap模块依赖jquery ,所以在要用到bootstrap时,
//requireJs 会先将jquery加载进来才会执行bootstrap。
//requireJs用这种方式来保证各个文件间的倚赖关系,并保证引用顺序。
},
backbone: {
deps: ['underscore', 'jquery'], //多个依赖关系以数组形式指定出来。
exports: 'Backbone' //加载完成后,用Backbone作为全局的模块ID(moduleID)
},
}
}

requirejs.config(requireConfig); //这样看起来是不是和平时用的插件的调用方式差不多了呢。:)

define(function(require){ //定义一个模块,传入require对象。并执行函数。
'use strict'

require(['bootstrap'],function(){ //第一个参数传入函数内需要依赖的模块,因为在上面的shim配置中,已经指定了bootstrap倚赖于jquery,
//所以,这里调用bootstrap时,虽然没指定加载jquery,但requireJs依然会先将jquery加载进来。
//这就是指定js间依赖关系的好处。

try{
console.log('OK'); //输出==>'OK'
console.log($); //输出==>' function(selector, context)'
//到这里这个模块已经能正常工作了,此时页面中加载了三个脚本:require.js , jquery.js ,bootstrap.js。
//其它的模块还没开始使用,所以这里require也不会加载上面所有的js文件进来。这就是requireJs的按需加载。

}catch(e){ ,
console.error(e);
}
});

})

依照上面的配置,便通过requireJs的方法引入了jquery和bootstrap。但实际的模块化开发中,一个应用是有很多个模块的,那怎么新建一个自己的模块呢?

Mustache.js以及text.js组件的应用:
在上面的目录结构中,module文件夹放的是自己的功能模块。接下来我在mainContext.js中定义一个模块,在这个模块中初始化页面,并绑定事件。

先看一下模板文件的样子,好对下面的操作有个理解:
context.html:

<h1>这是第一个标题:{{{ first }}}</h1>
<h1>这是第二个标题:{{{ second }}}</h1>
<!--{{}}两个花括号不会解析html标签,{{{}}}三个花括号会解析html标签。
<div>
这是一个按钮:{{{ btnTxt }}}
</div>


button.html:
<button id='btn_temp'>{{{ btnTempTxt }}}</button>
接下来是mainContext.js的代码:
define(function(require){ //定义一个模块,传入require对象。并执行函数。
'use strict'

var Mustache=require('mustache'), //引入mustache,为后面模板渲染。
Keyword=require('text!../../html/context.html'), //用text.js引入模板文件,这里的格式是:“text.js的ID+!+模板路径“,
//“text!../../html/context.html”中,"text"是mainFrame中定义的text.js的moduleID,并不是固定用“text”,
//“!”用于分隔moduleID和路径,后面模板的路径是相对于当前文件的路径,这个就是相对于mainContext.js的
//路径,具体可在上面的结构目录中对比一下。
Tbutton=require('text!../../html/button.html');

function MainContent(div){ //
this._init(div);
this._bindEvent();
this.sayHello=function(){ //增加一个方法,后面测试用。
alert('Hello!')
}
}

MainContent.prototype._init = function (div) { //扩展MainContent函数。传入一个需初始化的元素。

var content = Mustache.render(Keyword, { //这里是Mustache.js的用法,传入模板和渲染的数据。具体用法参考官方示例,
first: 'RequireJs',
second: 'Mustache',
btnTxt: template(Tbutton, { //我这里做了一个嵌套的渲染,即在一个模板中渲染另一个模板。通过下面的template()函数给Mustache换了个名字,
//以便区分。但实际是一样的。
btnTempTxt: '嵌套的按钮'
})
});

// var button = Mustache.render(Tbutton,{
// btnTxt : 'BIGBUTTON'
// })

div.html(content); //通过jquery的html()方法将渲染出来的content添加进去。
}

MainContent.prototype._bindEvent=function(){ //给渲染的按钮添加点击事件,点击变换颜色。
$('#btn_temp').on('click',function(){
$(this).css('color','red')
})
}

function template(temp,content){
return Mustache.render(temp,content)
}

return MainContent; //返回MainContent对象。
})

//平时要正常使用到这个MainContent对象一般是怎么做的呢?反正我是通过 "new"操作符来实例化该函数。
//这里我们将MainContent作为一个对象用return返回给了调用者。所以我们只需要考虑怎么加载到其它页面并调用。

模块的调用:
requireJs通过require()方法来调用一个模块:“require(moduleID)”;
回到之前的MainFrame.js中,我们在其中调用这个模块并初始化用户界面。因为config配置和上面的第二段中的不变,这里只贴出了mainFrame.js中的define模块的代码。

define(function(require){
'use strict'
var MainContext=require('module/mainContext'); //requireJs通过require(moduleID)方法调用一个模块,如果没有给模块指定moduleID
//则需要指出模块路径。这里通过require()方法,便引入了mainContext.js并将其中的
//MainContent对象赋值给MainContext变量,后面操作MainContext和操作MainContent是一样的了。

require(['bootstrap'],function(){
try{
console.log('OK');
var div=$('#context'); //通过jquery选取主页上的需要初始化的区域。
var frame = new MainContext(div); //通过 “new” 操作符实例化MainContext对象,
frame.sayHello(); //此处也能调用到MainContext对象的sayHello()方法;
}catch(e){
console.error(e);
}
});

})

通过上面的实例化,页面从便有了内容,还有了简单的点击事件:
页面初始化时渲染了页面并调用了sayHello()方法:



页面初始化后的样子:



给按钮绑定了click事件:



下面给出示例里面的代码:

requirejs.config({
//默认从 js/ 中加载模块
baseUrl: 'js/',
paths : {
text:'thirdLib/requirejs/text',
mustache:'thirdLib/mustache.min',
jquery:'thirdLib/jqueryjs/jquery-2.1.4',
bootstrap:'thirdLib/jqueryjs/bootstrap.min'
},
shim : {
'bootstrap':{
deps:['jquery']
}
}
});

define(function(require){
'use strict'
var MainContext=require('module/mainContext');
var frame
require(['bootstrap'],function(){
try{
console.log('OK');
console.log($)
var div=$('#context');
frame = new MainContext(div);
frame.sayHello()
}catch(e){
console.error(e);
}
});

})

mainContext.js的代码:

define(function (require) {
'use strict'

var Mustache = require('mustache'),
Keyword = require('text!../../html/context.html'),
Tbutton = require('text!../../html/button.html');

function MainContent(div) {
this._init(div);
this._bindEvent();
this.sayHello=function(){
alert('Hello!')
}
}

MainContent.prototype._init = function (div) {

var content = Mustache.render(Keyword, {
first: 'RequireJs',
second: 'Mustache',
btnTxt: template(Tbutton, {
btnTempTxt: '嵌套的按钮'
})
});

div.html(content);
}

MainContent.prototype._bindEvent=function(){
$('#btn_temp').on('click',function(){
$(this).css('color','red')
})
}

function template(temp, content) {
return Mustache.render(temp, content)
}

return MainContent;
})

到这里require的基本用法就是这样了,常规的项目使用已经足够使用,相信你在这样做出一个小的例子并运行通便能对requireJs有了初步的了解,并进行使用,熟悉了便可以尝试多做些实验,多增加几个模块相互引用,相信那样会更加理解其中的运行机制。还可以去浏览器中看一下define和require两个对象的区别和主要作用。这里就需要大家自己去尝试分析啦!

用r.js压缩代码:
最后介绍一下requireJs的 r.js,这是requireJs提供的一个配套压缩插件,但必须依赖node环境,要使用它压缩项目代码,请先安装nodeJs环境。
在压缩前,r.js也需要一个配置文件配置压缩路径以及各文件间的倚赖关系,如下:

({
appDir:'./',//源目录
baseUrl:'js', //指定js文件基本路径。
dir:'./build',//目标目录:将压缩的文件保存到 build文件夹,命名不限。
paths : {
text:'thirdLib/requirejs/text',
mustache:'thirdLib/mustache.min',
jquery:'thirdLib/jqueryjs/jquery-2.1.4',
bootstrap:'thirdLib/jqueryjs/bootstrap.min'
},
shim : {
bootstrap:{
deps:['jquery'] //也需要指定倚赖关系。
}
},
modules:[{
name:'module/mainContext'
}],
fileExclusingRegExp:/^(r|build)\.js$|^(.git)|^(.vscode)$/ //指定需要忽略的文件类型
})

接下来打开windows系统的
cmd或者Linux的terminal,:

(cd = 打开文件夹)cd  到项目的根目录:





到了当前目录后 执行以下命令:

node ./js/thirdLib/requirejs/r.js -o build.js
之后nodeJs会执行压缩程序:



如正常运行,就能看到build文件夹中有了和项目结构一样的文件,但已经被压缩过了。如不能成功压缩,请仔细检查执行路径,以及node环境是否安装正确。

以上便是我接触到的require整个结构和常用组件的一个介绍。希望能对看到的人有一定的帮助。同时如果有什么问题或不足,希望能指出来。我会及时修正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息