1、为什么使用require.js
作为命名空间;
作为命名空间使用;
异步加载js,避免阻塞,提高性能;
js通过require加载,不必写很多script
2、require.js的加载
下载后,放在指定目录就可以加载了
- <script src="js/require.js"></script>
- <script src="js/require.js" defer async="true" ></script>
这种写法虽然简单,但其实并不推荐,一般的写法还要再加个属性:
- <script data-main="js/main" src="js/require-jquery.js"></script>
1、加载了 require-jquery.js 文件。注意,官方提供了 require.js和 jquery 的打包版本,推荐。
2、在加载之后,加载入口文件 js/main.js ,注意,main.js 写进去的时候,不需要后缀名。
你的所有其他 js 模块文件,都可以写在 main.js 里面,通过 main.js 加载。
3、require.js的配置
在data-main指定的主文件中,通过require.config来配置,并加载其他js模块
- require.config({
- baseUrl: 'js/',
- paths: {
- "backbone": "backbone",
- "underscore": "underscore"
- },
- shim: {
- "backbone": {
- deps: [ "underscore" ],
- exports: "Backbone"
- },
- "underscore": {
- exports: "_"
- }
- }
- });
paths:模块加载路径
shim:加载非AMD规范模块
- exports值(输出的变量名),表明这个模块外部调用时的名称;
- deps数组,表明该模块的依赖性。
- 主模块可以将项目基础模块加载加来并定义全局方法等
-
- require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
- // some code here
- });
4、定义模块(符合AMD规范)
require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。
假定现在有一个math.js文件,它定义了一个math模块。那么,math.js就要这样写:
- // math.js
- define(function (){
- var add = function (x,y){
- return x+y;
- };
- return {
- add: add
- };
- });
- // main.js
- require(['math'], function (math){
- alert(math.add(1,1));
- });
- define(['myLib'], function(myLib){
- function foo(){
- myLib.doSomething();
- }
- return {
- foo : foo
- };
- });
定义的模块返回函数个数问题
1、define 的return只有一个函数,require的回调函数可以直接用别名代替该函数名。
2、define 的return当有多个函数,require的回调函数必须用别名调用所有的函数。
- require(['selector','book'], function(query,book) {
- var els = query('.wrapper');
- book.fun1();
- book.fun2();
- });
5、加载js文件
到此为止,我们遇到了两个关键词,一个是 define ,可以用来定义模块(命名空间),第一部分我们讲了;还有一个是 require,可以直接加载其他 js。它除了简单的用法:- <script>
- require( ["some" ] );
- </script>
- <script>
- require(["aModule", "bModule"], function() {
- myFunctionA(); // 使用 aModule.js 中的函数 myFunctionA
- myFunctionB(); // 使用 bModule.js 中的函数 myFunctionB
- });
- </script>
6、requ.js插件
require.js还提供一系列插件,实现一些特定的功能。
domready插件,可以让回调函数在页面DOM结构加载完成后再运行。
- require(['domready!'], function (doc){
- // called once the DOM is ready
- });
- define([
- 'text!review.txt',
- 'image!cat.jpg'
- ],
- function(review,cat){
- console.log(review);
- document.body.appendChild(cat);
- }
- );
在 require 一个 js 文件的时候,一般不需要加上后缀名。如果加上后缀名,会按照绝对路径加载。没有后缀名,是按照下面的路径加载:
也就是默认加载 data-main 指定的目录,即 js/main.js 文件所在的目录。当然,你可以通过配置文件修改。
2、define 定义模块方法只能用在独立的js文件中,不能在页面中直接使用。
否则会报 Mismatched anonymous define() module 错误。
- <script data-main="js/main" src="js/require-jquery.js"></script>
2、define 定义模块方法只能用在独立的js文件中,不能在页面中直接使用。
否则会报 Mismatched anonymous define() module 错误。
1、cdn回退
其支持当CDN加载不正确时,回退加载本地相应的库。我们可以通过require.config达到这个目的:
- requirejs.config({
- paths: {
- jquery: [
- '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
- 'lib/jquery'
- ]
- }
- });
当你写一个没有任何依赖的模块,并且只是返回一个对象包含一些功能函数,那么我们可以使用一种简单的语法:
- define({
- forceChoke: function() {
- },
- forceLighting: function() {
- },
- forceRun: function() {
- }
- });
3、循环依赖
在一些情况中,我们可能需要模块moduleA和moduleA中的函数需要依赖一些应用。这就是循环依赖。
4、得到模块的地址
- // js/app/moduleA.js
- define( [ "require", "app/app"],
- function( require, app ) {
- return {
- foo: function( title ) {
- var app = require( "app/app" );
- return app.something();
- }
- }
- }
- );
如果你需要得到模块的地址,你可以这么做……
5、JSONP
我们可以这样处理JSONP终端:
- var path = require.toUrl("./style.css");
我们可以这样处理JSONP终端:
- require( [
- "http://someapi.com/foo?callback=define"
- ], function (data) {
- console.log(data);
- });
9、r.js压缩
Require.js 提供一个脚本 r.js ,可以将所有使用到的模块压缩成一个脚本文件,r.js 可以使用 Node.js 来执行。
在压缩模块前,需要写一个配置文件,说明主模块名,压缩后的文件名,哪些模块不要压缩
没有使用 define 定义的模块都不要压缩,包括 jQuery,backbone 等库及其插件