一、 requirejs
4.1 体验requirejs
requirejs是第一个模块化开发框架,提出了module transports规范, 基于前段模型的规范(加载时都是异步的),又借鉴于nodejs,也支持comminjs规范,建议我们使用module transports 规范
requirejs是基于AMD规定
require.js官网
requirejs.org
requirejs.cn
使用requirejs跟seajs一样要在页面中引入文件才可以使用
根目录:
如果没有data-main属性, 默认是以html文件为根目录
如果使用data-main属性, 默认是以data-main属性值为根目录
seajs是以seajs所在的文件目录为根目录
requirejs是以引入html文件的目录为根目录
引入requirejs会向全局暴露3个变量
require和requirejs是一样的
这里的require方法和seajs中seajs对象一样
引入requirejs的script标签上有一个data-main属性,它可以引入项目的入口文件
1 <script type="text/javascript" data-main="js/main.js" src="js/require.js"></script> |
除了以上方式还有另外一种方式可以引入项目的入口文件
require方法和sejas.use方法一样的,它也可以引入入口文件
接受两个参数
第一个参数是模块的依赖集合
必须是数组
第二个参数是回调函数
回调函数中的参数就是前面模块向外暴露的功能 (一一对应的)
作用域是window
requirejs对js文件敏感,因此可以省略.js后缀
1 <script type="text/javascript"> 2 // 引入入口文件 3 require(["js/main.js"], function(main) { 4 console.log(this); 5 console.log(main); 6 }) 7 </script> |
4.2 定义模块
requirejs和seajs一样, 都有一个define方法,用来定义模块
可以传递一个参数:
值类型 不能字符串
对象 require也支持
函数
此时函数遵循commonjs规范,requirejs提供了参数注入的技术,想要使用哪个模块就要注入哪个模块
向外暴露功能一定是基于commonjs规范
如果没有注入参数
作用域是window
如果注入参数
作用域是向外暴露功能的对象
可以传递两个参数:
第一个参数是一个字符串
第一个参数还可以是数组
第二个参数加载模块的函数
如果第一个参数是字符串,表示模块的id,此时函数遵循commonjs规范(与上面传递函数的表现形式一致)
如果第一个参数是数组, 表示模块的依赖集合, 此时函数遵循的是module transports规范,
如果想要使用哪个模块,就必须在依赖集合中注入哪个模块,包括内置模块(require, exports, module),此时函数中的参数是和前面模块向外暴露的接口是一一对应。
如果注入exports和module
作用域指向向外暴露功能的对象
如果没有注入exports和module
作用域是window
可以传递三个参数:
第一个参数是字符串,表示模块的id
第二个参数是数组,表示模块的依赖集合
第三个参数是回调函数,此时的函数遵循module transports 规范
在module transports规范中,定义的任何模块文件,都不要与内置模块的名称相同(require, exports, module)
在工作中,最后一种方式是最常用的(id一定要与模块路径统一)
1 // 定义模块 2 // 值类型 3 define(1); 4 // 这种方式是不允许的 5 define("abc"); 6 define(true); 7 8 // 传入对象 9 define({ 10 color: "red" 11 }) 12 13 // 传递函数 14 define(function(require, exports, module) { 15 console.log(this); 16 console.log(arguments); 17 this.color = "red"; 18 }) 19 20 // 传递两个参数,第一参数是字符串 21 define("dom", function(require, exports, module) { 22 console.log(this); 23 console.log(arguments); 24 }) 25 26 // 传递两个参数,第一个参数是数组 27 define(["color", "require", "exports", "module"], function(color, require, exportsm, module) { 28 console.log(this); 29 console.log(arguments); 30 this.color = "blue"; 31 }) 32 33 // 传递三个参数 34 define("dom", ["color", "require", "exports", "module"], function(color, require, exports, module) { 35 console.log(this); 36 console.log(arguments); 37 }) |
4.3 引入具有id的模块
当一个模块没有id的时候可以直接引入
当一个模块有id,此时无法直接引入
第一步要在模块依赖集合中加载模块文件
第二步通过require方法指定id(require是异步方法)
comminjs规范不能加载具有id的模块
1 // 加载具有id的模块 2 define(["dom", "require"], function(dom, require) { 3 require(["myId"], function(dom) { 4 console.log(dom) 5 }); 6 }) |
dom.js
1 define("myId", { 2 color: "red" 3 }) |
4.4 模块的覆盖关系
如果一个模块文件中有两个没有id的模块,前面的覆盖后面的模块
如果模块文件中有两个相同id的模块, 前面的覆盖后面的模块
如果一个模块文件中有两个不同id的模块,是可以同时存在的
1 // 两个没有id的模块 2 define({ 3 a: 2 4 }) 5 define({ 6 a: 1 7 }) 8 9 10 // 有两个相同id的模块 11 define("myId", { 12 a: 2 13 }) 14 15 define("myId", { 16 a: 1 17 }) 18 19 // 两个不同id的模块 20 define("myId1", { 21 a: 1 22 }) 23 24 define("myId2", { 25 a: 2 26 }) |
4.5 接口定义
在seajs中定义接口的方式:
exports.接口
module.exports.接口
module.exports = 值类型
module.exports = 对象
module.exports = 函数
以上方式都是基于commonjs规范, requirejs同样适用
return 值类型
return 对象
return 函数
以上三种方式,是基于(module transports)规范的,因为不依赖于 require, exports, module
开发更灵活
define 可以接受值类型
不能接受字符串
除了以上十种方式,当模块函数中注入exports和module的时候,作用域是向外暴露功能的对象,
因为可以通过this向外暴露接口
1 // 定义模块 2 define(function(require, exports, module) { 3 // console.log(this); 4 // console.log(arguments); 5 // 这种方式绝对不允许 6 exports = { 7 8 } 9 }) 10 11 // // commonjs 12 define(function(require, exports, module) { 13 // 第一种 14 exports.a = 1; 15 16 // 2 17 module.exports.a = 1; 18 19 // 3 20 module.exports = 123; 21 22 // 4 23 module.exports = { 24 a: 1, 25 b: 2 26 } 27 28 // 5 29 module.exports = function() {} 30 }) 31 32 33 // module transports 34 define(function() { 35 6 36 return 123; 37 38 7 39 return { 40 a: 1, 41 b: 2 42 } 43 44 8 45 return function() {} 46 }) 47 48 49 // 9 50 define(1); 51 define(true); 52 define("abc"); // 这种方式不允许 53 54 55 // 10 56 define({ 57 a: 1, 58 b: 2 59 }) 60 61 // this 62 define(function(require, exports, module) { 63 console.log(this); 64 console.log(arguments); 65 this.color = "red"; 66 }) |
4.6 模块对象
id: 表示的是模块的id, 默认值与uri不一致
uri: 模块的文件地址, 是相对于html文件目录
如果没有data-main属性, 路径的前面会多一个./
config: 配置模块信息的
exports: 暴露功能的接口对象
1 |
二、 配置
配置:本身具有这种功能,需要开启, 所以要进行配置
requirejs提供了config方法用于配置模块的
1.1 paths
作用:简化路径
值是一个对象
key: 新的路径
value: 原始路径
1 // 使用config配置 2 requirejs.config({ 3 // 配置paths 4 paths: { 5 "module": "module/header" 6 } 7 }) 8 9 define(["module/header"], function(header) { 10 console.log(header); 11 }) |
1.2 shim
作用: 将文件转为模块
值是一个对象
key: 模块路径
value 是一个配置对象
配置接口 exports
配置依赖集合 deps
1 // 使用config配置 2 requirejs.config({ 3 // 配置shim 4 shim: { 5 "lib/jquery-1.12.2": { 6 // 配置接口 7 exports: "$", 8 deps: [] 9 } 10 } 11 }) 12 13 define(["module/header/header"]); |
1.3 map
作用:配置模块文件
属性是一个路径
value 是一个对象
key: 引入的模块文件
value: 修改的模块文件
1 // 使用config配置 2 requirejs.config({ 3 // 配置shim 4 shim: { 5 "lib/jquery-1.12.2": { 6 // 配置接口 7 exports: "$", 8 // 配置依赖集合 9 deps: [] 10 }, 11 "lib/jquery100": { 12 // 配置接口 13 exports: "$", 14 // 配置依赖集合 15 deps: [] 16 } 17 }, 18 // 配置map 19 map: { 20 "module/header": { 21 "lib/jquery": "lib/jquery-1.12.2" 22 }, 23 "module/footer": { 24 "lib/jquery": "lib/jquery100" 25 } 26 } 27 }) 28 29 define(["module/header/header", "module/footer/footer"]); |
1.4 baseUrl
作用: 更改根目录的
优先级关系: baseUrl > data-main > require
1.5 css插件
requirejs不能直接引入css文件
在requirejs中引入css要当做模块来引入,需要配置
map {
“*”: {
css: 文件目录
}
}
在模块文件中要加上css!前缀
扫描下方二维码添加微信:haomei0452,领取 前端资料、项目实战视频教程 !
爱创课堂是一家专门做前端培训的机构,由百度高级工程师,《JavaScript设计模式》作者张容铭老师亲自授课,全程20个项目实战,真正做到学习完即可到企业正常工作!
我们前端课程的五大优势:
1. 名师亲自授课,根据企业需求 实时跟进课程大纲,保证学员学到的都是最新的、企业最需要的前端知识点
2. 采取小班教学、上二休一的模式(一个班20—30人,保证老师可以照顾到每一位同学,学员有充足的时间练习)
3. 签订就业协议,帮助学员制作简历,投递简历,模拟面试,不用担心就业问题,目前学员平均就业薪资12K
4. 免费学习一周,不满意不收取任何费用
5. 与中国石油,中国电信,软通等知名企业合作,进行企业内训,并进行学员就业推荐