JavaScript 模块化开发实例详解【seajs、requirejs库使用】
本文实例讲述了JavaScript模块化开发。分享给大家供大家参考,具体如下:
JS开发的问题
-
冲突
-
依赖
-
JS引入的文件,产生依赖.
使用命名空间解决:
-
命名空间的弊端
-
调用的时候名字比较长.
-
只能减低冲突,不能完全避免
SeaJs使用
-
引入sea.js的库
-
如何变成模块?define
-
如何调用模块?exports和seajs.use
-
如何依赖模块?require
//html://console.log(seajs); seajs.use('./js/main.js',function(main){ main.show(); });
//main.js define(function(require,exports,module){ varheader=require('./header.js'); functionshow(){ alert(123); } exports.show=show; });
seajs.use()
加载一个或多个模块
//加载一个模块 seajs.use('./main.js'); //加载一个模块,在加载完成时,执行回调 seajs.use('./main.js',function(main){ }); //加载多个模块,在加载完成时,执行回调 seajs.use(['./main.js','./b'],function(a,b){ a.doSomething(); b.doSomething(); });
seajs.use与DOMready事件没有任何关系。如果某些操作要确保在DOMready后执行,需要使用jquery等类库来保证。
seajs.use(['jquery','./main'],function($,main){ $(function(){ main.init(); }) });
use方法第一个参数一定要有,但是可以是null,也可以是一个变量
varapp=['app.js','header.css','header.js']; seajs.use(app,function(app){ //dosomething });
seajs.use()只用于加载启动,不应该出现在define的模块代码中,如果模块代码里需要加载其它模块时,使用require(),需要加载异步其它异步模块时,使用require.async()
seajs.use是模块加载器必备的一个接口
define函数
当传递一个参数时候,那么这个参数就是一个模块,参数可以是任意类型
传递一个字符串,那么这个模块就是一个字符串模块
传递一个对象的时候,那么这个模块就是一个对象模块
传递一个函数(最常用的方式)
这函数自带三个参数
Require:引用其他模块的工厂方法
Exports:返回的接口对象
Module:模块module属性
当传递过参数时(两个,或者三个)
如果传递两个参数的时候,第一个该模块依赖的模块数组集合,最后一个参数是function
如果传递三个参数的时候,第一个表示该模块的名称,第二个参数表示该模块依赖的模块集合,第三个
//第一个参数,当前模块的ID,也就是当前模块的地址 //第二个参数,以来模块的地址的数组 define('./main.js',['./drag.js'],function(require,exports,moduels){ });
三个参数解释
require
-
require不能简写
-
require不能被重定义
不能赋值:varreq=require
不能定义函数:functionrequire
不能被子函数当成参数
不能在子函数作用域内重定义//错误-重命名"require"!
varreq=require,mod=req("./mod");//错误-重定义"require"!
require=function(){};//错误-重定义"require"为函数参数!
functionF(require){}//错误-在内嵌作用域内重定义了"require"!
functionF(){varrequire=function(){};
}
-
require的参数只能是完整的字符串require(‘abc'+‘bcd')是不允许的
exports
-
模块的接口
-
第一种,直接对exports添加属性,如exports.color='red'
-
第二种,通过module来定义,module.exports.color='red'
-
第三种,通过module来定义,module.exports={color:'orange'}
-
第四种,通过return来定义,return{color:'green'}
-
在一个模块中定义接口时候要用一种方式,不能混用
-
注意,不可以直接对exports赋值新对象
module
-
模块的属性
-
id:表示模块的id
-
uri:表示该模块文件对应的url
-
exports:表示模块返回的接口集合
-
dependencies:表示依赖模块集合(数组表示形式)
-
deps:表示依赖模块集合(对象表示形式)
CMD模块定义规范
一个模块就是一个文件
define是一个全局函数,用来定义模块
define(facotry)
facotry可以是一个函数,也可以是一个对象或字符串
definde({color:'tan'});
当参数为函数时。默认会有三个参数:require,exports,module
definde(function(require,exports,module){ });
define([id,deps],factory)
define也可以接受两个以上的参数,字符串id表示模块标识。deps是模块依赖。
define('main',['mina.js'],function(require,exports,module){ //模块代码 });
id,deps参数省略,可以通过构建工具自动生成。
id和deps参数,不属于CMD规范。
requirefunction
require是一个方法,接受模块标识作为唯一参数,用来获取其他模块提供的接口。
deifne(function(requrie,exports){ //获取模块main的接口 varmain=require('./main'); //调用模块main中的定义方法 main.init(); });
require.async(id,[cb]);
模块内部异步加载模块,并在加载完成后执行指定的回调函数。
require.async('./a',function(){}); //加载多个异步模块 require.async(['./a','./b'],function(){});
//异步加载所需要的模块 define(function(require,expotrs,module){ varloadSync=false; if(loadSync){ varskin=require.async('./skin'); }else{ varheader=require.async('./header'); } });
exports
exports,用来向外提供模块接口
define(function(require,exports,module){ //对外提供foo属性 exports.color='pink'; //对外提供doSomething方法 exports.doSomething=function(){}; });
通过return提供接口
define(function(){ //通过return直接提供接口 return{ color:'deeppink', sayName:function(){} } });
CMD模块中,经常使用的API有:define,require,require.async,exports,module.expotrs
seajs配置
seajs.config()
alias
定义模块别名
当引用一些基础库的时候,涉及到基础库升级,在alias中定义这个模块时,修改只需要修改这个别名配置。
seajs.config({ alias:{ jquery:'lib/jquery.1.10.1' } });
模块中使用
require('jquery');
paths
定义模块路径
一些模块创建目录结构很深的时候,可以将这个层级定义成一个简写的path,引用这个模块的时候,直接通过pathName+模块名称。
seajs.config({
paths:{ hd:'./modules/header' }
});
模块中使用
require('hd/header.js');
vars
在某些情况下,模块路径在运行时才能确定,可以使用vars变量来配置。
seajs.config({ vars:{ skin:'header/skin' } });
模块中使用
require('{skin}/skin.js');//需要使用{}来标识
map
映射配置,匹配文件,做映射处理
开发完一些模块时候,需要打包或压缩处理,此时文件名可能会不同,可以通过map映射,来找到这个文件,修改成对应的文件名
seajs.config({ map:[ ['main.js','main-min.js'] ] }); seajs.use(['main'],function(main){ //do... });
base
设置模块的根目录
有时候开发用seajs不一定在当前页面目录下,此时想引用这个模块比较麻烦,可以通过base来重定义该页面模块文件根目录。
charset
设置模块的编码格式
seajs.config({ charset:'utf-8' });
seajs.config({ charset:function(url){ //xxx目录下的文件用gbk编码加载 if(url.indexOf('http://example.com/js/xxx')===0){ return'gbk'; } //其他文件用utf-8编码 return'utf-8'; } });
常用的配置项:alias,paths,base
seajs插件
seajs-preload.js
加载js文件
seajs.config({ //预加载jquery文件 preload:['jquery.js'] });
模块中文件使用
definde(function(require,exports,module){ $(document).css('background','tan'); });
seajs-css.js
加载css文件
definde(function(require,expotrs,module){ require('../css/css.css'); });
requireJs
引入模块文件时候,requirejs是根据引用了require文件的script标签中data-main属性对应的文件所在的目录
define定义模块
传递一个对象可以
传递一个函数(commonjs规范的实现)
区别在于module
id表示模块的id,id没有后缀名(注意:seajs有后缀名)
没有依赖的模块集合
config配置属性
模块接口
在AMD规范定义的模块中,没有exports参数,只能通过return将接口暴露出来。
-
return对象,这种方式可以将模块内部多个属性多个方法暴露出来。
-
return方法,这种方式将一个方法返回出来,引用这个模块就是引用这个接口方法,在它父模块(引用它的模块中)可以直接调用该方法。是在自己模块的作用域中。
requirejs配置
baseUrl
设置根目录
用途:有时候启动文件不在预期的位置,可以通过baseUrl来设置根目录
require.config({ baseUrl:'lib' });
paths
简写路径
require.config({ paths:{ hd:'module/header' } });
map
当存在多个页面,可能每个页面引用代码库不一样,可以通过map进行配置,对每个文件配置不同的代码库文件。
require.config({ map:{ //modules模块下的dom模块引用的是lib/dom 'modules':{ 'dom':'lib/dom' }, //modules-new模块下的dom模块引用的是lib/dom.2.0 'modules-new':{ 'dom':'lib/dom.2.0' } } });
使用css插件
requireJs加载css插件
//配置 require.config({ map:{ '*':{ 'css':'lib/css' } } });
//使用 define(['css!css/index.css'],function(){ });
shim
表示配置模块依赖关系
对于一些定义在全局作用域下的代码库,常常获取不到这类库的模块,此时通过定义shim的莫开依赖关系,可以在模块中获取到这类代码库。
require.config({ shim:{ 'lib/jquery':{ //依赖的模块集合 deps:[], expotrs:'$' } } });
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。