require.js疑惑

        昨天小穎分享了一篇require.js入門 ,今天小穎發現了一個很鬱悶的問題,但願大神們幫小穎解釋下究竟是什麼原理才能出現如下的現象,其實小穎昨天也有問過園友裏的一位帥鍋,只是他解釋的小穎沒太明白。嘻嘻因此寫出來想經過博客園這個平臺裏集思廣益,解決這個疑惑。css

       好啦咱們一塊兒來看看這個讓小穎頭疼的問題:html

       demo目錄:jquery

                                       

      代碼來啦:數組

    咱們先來看看正常代碼吧:

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

    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.jsasync

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

有變化的文件哦:函數

app.jsrequirejs

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.jspost

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  的緣由是同樣的。小穎這樣的解釋能明白嗎?

相關文章
相關標籤/搜索