Require使用方法详细讲解

Require使用方法详细讲解


现在项目大都使用模块化开发,而 RequireJS 作为 AMD 模块开发的典范,还是很值得学习使用的。

一、AMD 规范

1,AMD 基本介绍

AMD 全称为 Asynchromous Module Definition(异步模块定义)
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出,它是一个在浏览器端模块化开发的规范。
AMD 模式可以用于浏览器环境并且允许非同步加载模块,同时又能保证正确的顺序,也可以按需动态加载模块。

2,AMD 模块规范

AMD 通过异步加载模块。模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。
AMD 规范只定义了一个函数 define,通过 define 方法定义模块。该函数的描述如下:

define(id?, dependencies?, factory)
id:指定义中模块的名字(可选)。如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。
dependencies:当前模块依赖的,已被模块定义的模块标识的数组字面量(可选)。
factory:一个需要进行实例化的函数或者一个对象。

AMD 规范允许输出模块兼容 CommonJS 规范,这时 define 方法如下:

define(function (require, exports, module) {
    var reqModule = require("./someModule");
    requModule.test();

    exports.asplode = function () {
        //something
    }
});

二、RequireJS 介绍

1,什么是 RequireJS

RequireJS 是一个 JavaScript 模块加载器。它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 比如 Rhino 和 Node。使用 RequireJS 加载模块化脚本将提高代码的加载速度和质量。

2,使用 RequireJS 的好处

异步“加载”。使用 RequireJS,会在相关的 js 加载后执行回调函数,这个过程是异步的,所以它不会阻塞页面。
按需加载。通过 RequireJS,你可以在需要加载 js 逻辑的时候再加载对应的 js 模块,不需要的模块就不加载,这样避免了在初始化网页的时候发生大量的请求和数据传输。
更加方便的模块依赖管理。通过 RequireJS 的机制,你能确保在所有的依赖模块都加载以后再执行相关的文件,所以可以起到依赖管理的作用。
更加高效的版本管理。比如原来我们使用的 script 脚本引入的方式来引入一个 jQuery2.x 的文件,但如果有 100 个页面都是这么引用的,如果想换成 jQuery3.x,那你就不得不去改这 100 个页面。而使用 requireJS 只需要改一处地方,即修改 config 中 jQuery 的 path 映射即可。
当然还有一些诸如 cdn 加载不到 js 文件,可以请求本地文件等其它的优点,这里就不一一列举了。

三、RequireJS 的配置和使用

1,下载最新版的 require.js

下载地址:RequireJS

2,创建一个如下目录结构

(1)lib 文件夹下放置一些需要用到的 js 库,这里除了 require.js 外,还有 jquery等。
(2)script 文件夹下放置 RequireJS 的入口 js、以及模块 js 文件。
(3)index.html 则为主页面。
目录结构图

3,代码说明

  1. index.html :
<!DOCTYPE html>
<html>
	<head>
		<meta charset="gb2312" />
		<title>JS ModuleProgram</title>

		<script data-main="script/main.js" src="lib/require.js"></script>
	</head>

	<body>
		<div id="MessageBox"></div> <br>
		<button id="btn" type="button" name="button">Click</button>
	</body>
</html>
  1. main.js
'use strict';

//在此处定义要加载的脚本路径,如果此处没有定义,则在以后调用的时候指定加载路径
require.config({
    baseUrl: '../js_2', //设置js脚本加载的基础路径
    enforceDefine: true, //打开错误检查

    //路径支持数组,如果第一个加载不成功,会自动依次加载后面的地址,直到成功
    paths: {
        jquery: ['lib/jquery-3.4.1',
        		 'https://code.jquery.com/jquery-3.4.1.min.js'],
        hello: 'script/hello',
        constData: 'script/constData',
        alertMsg: 'script/AlertMsg'
    }
});

// 前置加载
require(['jquery', 'hello', 'constData'], function ($, hello, constData, canvas, sub) {
	$('#MessageBox').html(constData.ProjectName +  ' Load Successful!');

	$("#btn").click(function(){
		hello.showMessage("HelloWorld");
	});
}, function(err){
	// 获取加载错误的模块
	var failedId = err.requireModules && err.requireModules[0];
	switch(failedId){
		case 'jquery':
		    // 错误处理,可以重新选择加载模块的路径
			requirejs.undef(failedId);
			requirejs.config({
				paths: {
					jquery: 'local/jquery'
				}
			});
			require(['jquery'], function() {});
			break;
		case 'hello':
			alert('hello is error.');
			break;
		case 'constData':
			alert('constData is error.');
			break;
		default:
			break;
	}
});
  1. hello.js
'use strict';

//define中的[]定义本模块要加载的库,库的路径都在require.config中配置好了,
//function()参数中一一对应设置要使用的模块名称
define(['require', 'jquery', 'constData'], function(require, $, constData){
	var moduleName = "hello module";
	var moduleVersion = "1.0";

// 测试模块中的错误,仿真模块加载失败案例
//	var const = constData.name;
	var showMessage = function(name){
		if(undefined === name){
			return;
		}else{
			$('#MessageBox').html(constData.ProjectName + ' is Welcoming to ' + name);

			//可以使用require动态的在运行时获取一个模块
			require(['alertMsg'], function(alertMsg){
				alertMsg.AlertMessage('In the hello.js.');
			});
		}
	};

	//返回本模块的API
	return{
		"moduleName" : moduleName,
		"version" : moduleVersion,
		"showMessage" : showMessage
	};
});
  1. AlertMsg.js
'use strict';

define(function(require, exports, module){
	//直接使用CommonJS规范来获取定义的模块
	var constD = require('constData');
	var AlertMessage = function(msg){
		if(undefined === msg){
			return;
		}else{
			alert(constD.ProjectVersion + " --> " + msg);
		}
	};
	var getName = function(){
		return constD.ProjectName;
	}
	//也可以通过这种方式暴漏本模块的API
	exports.AlertMessage = AlertMessage;
	exports.getName = getName;
});
  1. constData.js
define({
	ProjectName: 'JSModuleTest',
	ProjectVersion: 'V1.0.0'
});

四. RequireJS的配置说明

要改变 RequireJS 的默认配置,可以使用 require.configh 函数传入一个可选参数对象。下面是一些可以使用的配置:

baseUrl:用于加载模块的根路径。在配置这个属性后,以后的文件都是在这个路径下查找内容了。
paths:用于一些常用库或者文件夹路径映射,方便后面使用,省得每次都要输入一长串路径。(js 文件的后缀可以省略)
shim:加载非 AMD 规范的 js,并解决其载入顺序。
require.config({
    baseUrl: 'js',
    paths: {
        jquery: 'lib/jquery-1.11.1'
    },
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'modal':{//模态框插件不是模块化
            deps:['jquery'],
            export:"modal"
        },
    },
    map: {
        'script/newmodule': {
            'foo': 'foo1.2'
        },
        'script/oldmodule': {
            'foo': 'foo1.0'
        }
    },
    config: {
        'script/bar': {
            size: 'large'
        },
        'script/baz': {
            color: 'blue'
        }
    }
});

1,baseUrl

用于加载模块的根路径。在配置这个属性后,以后的文件都是在这个路径下查找内容了。

2,paths

用于一些常用库或者文件夹路径映射,方便后面使用,省得每次都要输入一长串路径。(js 文件的后缀可以省略)

3,shim

虽然目前已经有一部分流行的函数库(比如 jQuery)符合 AMD 规范,但还有很多库并不符合。shim 就是为了加载这些非 AMD 规范的 js,并解决其载入顺序的。
比如上面样例,我们想通过 RequireJS 来使用 backbone,那么你就需要在配置中把它定义为一个 shim。同时通过 deps 配置其依赖关系,可以保证 underscore、jquery 先被加载。
shim配置的注意事项:
shim 配置仅设置了代码的依赖关系,想要实际加载 shim 指定的或涉及的模块,仍然需要一个常规的 require/define 调用。设置 shim 本身不会触发代码的加载。
请仅使用其他"shim"模块作为 shim 脚本的依赖,或那些没有依赖关系,并且在调用 define() 之前定义了全局变量(如 jQuery 或 lodash )的 AMD 库。否则,如果你使用了一个 AMD 模块作为一个 shim 配置模块的依赖,在 build 之后,AMD 模块可能在 shim 托管代码执行之前都不会被执行,这会导致错误。终极的解决方案是将所有 shim 托管代码都升级为含有可选的 AMD define() 调用。

4,map

(1)对于给定的模块前缀,使用一个不同的模块 ID 来加载该模块。该手段对于某些大型项目很重要。
比如上面配置以后,不同的模块会使用不同版本的"foo":
当 some/newmodule 调用了 require(‘foo’),它将获取到 foo1.2.js 文件。
当 some/oldmodule 调用 require(‘foo’),时它将获取到 foo1.0.js 文件。

(2)map 还支持“”,意思是“对于所有的模块加载,使用本 map 配置”。如果还有更细化的 map 配置,会优先于“”配置。
比如下面配置,除了“some/oldmodule”外的所有模块,当要用“foo”时,都使用“foo1.2”来替代。

requirejs.config({
    map: {
        '*': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

5,config

我们需要将配置信息传给一个模块。这些配置往往是 application 级别的信息,需要一个手段将它们向下传递给模块。这个通过 requirejs.config() 的 config 配置项就可以实现。

(1)可以通过加载特殊的依赖“module”来获取这些信息。

// script/info.js
define(['module'], function (module) {
    var color = module.config().color;  //blue
});

(2)也可通过符合 CommonJS 规范的模块获取

// script/info.js
define(function (require, exports, module) {
    var color = module.config().color;  //blue
});

五,相对路径规则

不管是在配置中写路径还是直接在 require 函数中写路径,我们需要了解 requireJS 在不同情况下的相对路径。以下是相对路径的规则:
如果

引用原文链接(有删改):原文链接

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值