昨天小颖分享了一篇require.js入门 ,今天小颖发现了一个很郁闷的问题,希望大神们帮小颖解释下到底是什么原理才能出现以下的现象,其实小颖昨天也有问过园友里的一位帅锅,只是他解释的小颖没太明白。嘻嘻所以写出来想通过博客园这个平台里集思广益,解决这个疑惑。

好啦我们一起来看看这个让小颖头疼的问题:

demo目录:

代码来啦:

我们先来看看正常代码吧:

  公用的文件index.html和ceshi.js

index.html

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<title>require.js小demo</title>
<!-- 加载require.js文件,也可能造成网页失去响应。解决办法有两个,一个是把它放在网页底部加载,另一个是写成下面这样: -->
<!-- <script src="js/require.js" defer async="true" ></script> -->
<!--async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上。 -->
<!-- 加载require.js以后,下一步就要加载我们自己的代码了。假定我们自己的代码文件是main.js,也放在js目录下面。只需要写成下面这样就行了: -->
<!-- <script src="js/require.js" data-main="src/main.js"></script> -->
<script defer async="true" data-main="app" src="js/require.js"></script>
</head> <body>
<div class="div-index">哈喽</div> </body> </html>

ceshi.js

define(function(require) {
var ad = function() {
return 'aaa';
};
return {
ad: ad
}
});

有变化的文件哦:

app.js

requirejs.config({
baseUrl: 'js/lib',
paths: {
cs:'ceshi',
jquery: '../jquery'
}
});
require(['main', 'jquery'], function(mains, jq) {
console.log(mains.add(2, 5));
console.log(jq);
});

main.js

define(['cs'],function(ceshi) {
console.log(ceshi.ad());
var add = function(x, y) {
return x + y;
};
return {
add: add
}
});

结果:

以下是有疑惑的几种情况:

第一种情况:

当小颖在app.js中加载jquery的时候,将 paths: { cs:'ceshi', jquery: '../jquery' }改成:paths: { cs:'ceshi', jq: '../jquery' }时:

app.js

requirejs.config({
    baseUrl: 'js/lib',
    paths: {
         cs:'ceshi',
        jq: '../jquery'
    }
});
require(['main', 'jq'], function(mains, jqs) {
    console.log(mains.add(2, 5));
    console.log(jqs);
    console.log($);
});

结果就变成了:

问题:小颖想问下为什么将在paths中在加载 ceshi.js 时,给其命名为 cs,在main.js中就能正常调到,而将 jquery 改成 jq  就到不到了呢?但是用jquery的 $ 符号却能调到这又是为什么?

第二种情况:

小颖在paths中不加载jquery.js和ceshi.js在用的时候再加载:

app.js

requirejs.config({
baseUrl: 'js/lib',
paths: {
// cs:'ceshi',
// jq: '../jquery'
}
});
require(['main'], function(mains) {
console.log(mains.add(2, 5));
});

main.js

define(['../jquery','ceshi'],function(jq,cs) {
  console.log(jq);
  console.log($);
  console.log(cs.ad());
    var add = function(x, y) {
        return x + y;
    };
    return {
        add: add
    }
});

结果:

问题:像上面那种加载方式加载jquery.js,为什么加载了 ceshi.JS ,后用回调函数中的别名 cs 却能调到,但是 jquery 用 jq 却调不到,但是用 $ 符号却能调到?

小颖的答案:

在上面的有问题的两种情况下,大家都发现只有给jquery重新起一个加载的名字,在打印这个别名时有问题,但按照AMD模块的写法写的ceshi.js起别名就是ok的,所以小颖觉得问题不在require.js上,问题应该出自jquery本身,小颖看了jquery源码后发现:

当小颖将define中的  jquery 删除 时,以上两种情况就ok啦:

原因:

define(name,[] , callback); 这个name可以省掉,默认是文件名称;当然也可以自定义,一旦我们定义了name,根据源代码我们可以发现define函数内部其实就是把这个name以及依赖模块、回调函数作为一个对象存储在全局的数组当中,也就是 defQueue.push([name,deps,callback]);那么这个name就是这个组件注册的的ID!

虽然小颖虽然在paths中将jquery起名为 jq,但是jquery自身已经通过define(name,[] , callback);命名成   jquery了,所以用后面再用jq就调不到了。

第一种情况:

app.js

requirejs.config({
    baseUrl: 'js/lib',
    paths: {
         cs:'ceshi',
        jq: '../jquery'
    }
});
require(['main', 'jq'], function(mains, jqs) {
    console.log(mains.add(2, 5));
    console.log(jqs);
    console.log(123+$);
});

小颖将jquery.js中的define里面的参数的  jquery 删除  时结果:

第二种情况:

app.js

requirejs.config({
baseUrl: 'js/lib',
paths: {
// cs:'ceshi',
// jq: '../jquery'
}
});
require(['main'], function(mains) {
console.log(mains.add(2, 5));
});

main.js

define(['../jquery','ceshi'],function(jq,cs) {
console.log(123+jq);
console.log($);
console.log(cs.ad());
var add = function(x, y) {
return x + y;
};
return {
add: add
}
});

小颖将jquery.js中的define里面的参数的  jquery 删除  时结果:

如果大家还是不太明白的话,小颖给大家再写个示例吧:

先看看目录吧:

index.html我就不给大家写出来了,那个大家在上面可以复制下来把  data-main  和   src 的值一修改就好了。

app.js

requirejs.config({
baseUrl: 'js/lib',
paths: {
css:'ceshi',
jqy: 'jquery'
}
});
require(['../app/main'], function(mains) {
console.log(mains.add(2, 5));
});

从上面的目录图片可以看出,小颖将 ceshi.js 、jquery.js 、require.js 这三个js放在同一个目录下,js下的lib下,在这个demo中,小颖把jquery文件define里面的参数的  jquery 删除  已经删除了,所以小颖可以给其任意起id名啦。这次叫的是  jqy。

lib下的ceshi.js

define('css',[],function(require) {
console.log('我的文件名叫ceshi(曾用名),我的实际叫css(现在的名字)');
var ad = function() {
return 'hello world';
};
return {
ad: ad
}
});

大家仔细看下上面代码中的第一行,小颖在ceshi.js中通过 define('css',[],function(require) {});已经将ceshi.js命名为  css  所以小颖在 app.js中加载ceshi.js时给的id是css,这样才能真正的加载到ceshi.js.

js/app/main.js

define(['jqy','css'],function(jq,cs) {
console.log(123+jq);
console.log(cs.ad());
var add = function(x, y) {
return x + y;
};
return {
add: add
}
});

结果:

如果小颖将app.js中加载ceshi.js的id改成与ceshi.js中命名的名字不一样的话:

requirejs.config({
baseUrl: 'js/lib',
paths: {
cs:'ceshi',
jqy: 'jquery'
}
});
require(['../app/main'], function(mains) {
console.log(mains.add(2, 5));
});

main.js

define(['jqy','cs'],function(jq,cs) {
console.log(jq);
console.log(cs);
console.log(cs.ad());
var add = function(x, y) {
return x + y;
};
return {
add: add
}
});

结果:

其实这时cs是 undefined    和上面小颖提的jquery是  undefined  的原因是一样的。小颖这样的解释能明白吗?

require.js疑惑的更多相关文章

  1. Javascript模块化编程(三):require.js的用法

    Javascript模块化编程(三):require.js的用法 原文地址:http://www.ruanyifeng.com/blog/2012/11/require_js.html 作者: 阮一峰 ...

  2. javascript模块化编程(三):require.js用法

    本文来自阮一峰 这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require ...

  3. require.js工作原理(初始)

    详情:请见阮一峰老师的日志:http://www.ruanyifeng.com/blog/2012/11/require_js.html: 导入:<script data-main=" ...

  4. Javascript模块化编程(三):require.js的用法(转)

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的 ...

  5. require.js源码分析

    写的寥寥草草,博客园的布局怎么弄还没有研究,再保存一份草稿,日后在完善,深度研究 require.js 加载顺序 1:加载html主页,require.js文件 2:脚本执行到html中的script ...

  6. Angular.JS + Require.JS + angular-async-loader 来实现异步加载 angular 模块

    传统的 angular 应用不支持异步加载模块,必须在 module 启动的时候,所有模块必须预加载进来. 通过使用 angular-async-loader 库,我们可以使用 requirejs 等 ...

  7. require.js

    日期: 2012年11月 7日 http://www.ruanyifeng.com/blog/2012/11/require_js.html 这个系列的第一部分和第二部分,介绍了Javascript模 ...

  8. require.js 入门笔记

    网站越来越庞大,JS也是越写越多. 当所有的JS 都集中在 HTML的 head 部分时,网页加载变得很慢,很多的 JS代码也并不是全都适用在当前的页面,造成了代码的冗余度非常高. 而且长长的JS代码 ...

  9. require.js 的使用

    一.为什么要用require.js 在同一个页面要加载多个js文件时,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长: 其次,由于js文件之间存在依赖关系,因此必须严格保证加载顺序(比 ...

随机推荐

  1. 自定义view(二)

    这里是自定义view(二),上一篇关于自定义view的一些基本知识,比如说自定义view的步骤.会涉及到哪些函数以及如何实现自定义属性,同时实现了一个很基础的自定义控件,一个自定义的计时器,需要看的人 ...

  2. 简单分析beyond作曲

    本人绝对是业余的哈 业余到什么水平呢?正在练习爬格子,还是一个星期练几次那种 先说下<海阔天空> 6,5,4,3 1,2,3,4 简单是简单得不得了,声从低到高,然后再从高到低,产生一种回 ...

  3. iOS回顾笔记(04) -- UIScrollView的基本使用详解

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  4. 【翻译】LPeg编程指南

    原文:http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html   译者序: 这个是官方的LPeg的文档.这段时间学习LPeg的时候发现国内关于LPeg的文章 ...

  5. request.RequestContextListener

    由于是使用spring mvc来做项目,因此脱离了HttpServletRequest作为参数,不能够直接使用request,要想使用request可以使用下面的方法: 在web点xml中配置一个监听 ...

  6. 【Rsync项目实战】备份全网服务器数据

    [Rsync项目实战]备份全网服务器数据 标签(空格分隔): Linux服务搭建-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转载,转 ...

  7. wemall doraemon中Android app商城系统向指定URL发送GET方法的请求代码

    URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...

  8. 1635: [Usaco2007 Jan]Tallest Cow 最高的牛

    1635: [Usaco2007 Jan]Tallest Cow 最高的牛 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 383  Solved: 211 ...

  9. [OpenGL] mac上运行NateRobin的OpenGL教程找不到 data file 解决方案

    之前买的OpenGL编程指南第七版一直没看,最近开始看了,然后按照教程推荐的去指定网址下载NateRobin的OpenGL教程,但发现网址已经提示Error:404了, 然后谷歌搜索到可用的下载网址为 ...

  10. Java 中的锁——Lock接口

    Java SE5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能.虽然它少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的操作性. ...