2013-06-27 55 views
14

我有腳本的非常簡單的目錄結構:要求JS無視我的配置

/js/  <-- located in site root 
    libs/ 
     jquery-1.10.1.min.js 
     knockout-2.2.1.js 
     knockout.mapping.js 
    models/ 
     model-one.js 
     model-two.js 
     ... 
    require.js 
    config.js 

由於該網站引擎使用乾淨的URL我使用絕對路徑在<script>

<script type="text/javascript" data-main="/js/config.js" src="/js/require.js"></script> 

RequireJS配置:

requirejs.config({ 

    baseUrl: "/js/libs", 

    paths: { 
     "jquery":  "jquery-1.10.1.min", 
     "knockout":  "knockout-2.2.1", 
     "komapping": "knockout.mapping" 
    } 

}); 

某處在HTML:

require(["jquery", "knockout", "komapping"], function($, ko, mapping){ 
    // ... 
}); 

所以問題是RequireJS完全忽略了配置文件中定義的baseUrlpaths。下面的代碼中所需的每個模塊都會收到404錯誤。我看到在RequireJS試圖加載從/js/這些模塊沒有任何路徑轉換瀏覽器控制檯:在頁面加載和顯示錯誤

404: http://localhost/js/jquery.js 
404: http://localhost/js/knockout.js 
404: http://localhost/js/komapping.js 

但是我在控制檯輸入和...

> require.toUrl("jquery") 
    "/js/libs/jquery-1.10.1.min" 

這是爲什麼?如何解決這個問題呢?

這是我第一次使用RequireJS的經驗,所以我覺得我跳過了一些非常簡單明顯的東西。請幫助。

更新

剛剛發現了這個問題:Require.js ignoring baseUrl

這絕對是我的情況。我在我的網絡面板中看到config.jsrequire(...)激發自己的依賴加載之前未完全加載。

但我不想將我的require(...)置於配置中,因爲它對於調用它的頁面非常具體。在以前看過的任何例子中,我從來沒有注意到這種異步性問題。這些例子的作者如何讓他們工作?

+0

你嘗試先刪除斜槓 'JS /庫/'? – paka

+0

@paka剛試過。沒有變化。 –

+0

它與絕對路徑一起工作嗎? – paka

回答

22

已解決。

問題是data-main屬性中定義的配置文件是異步加載的,就像其他依賴項一樣。所以我的config.js意外地在require調用之前從未完全加載和執行。

該解決方案在正式RequireJS API描述:http://requirejs.org/docs/api.html#config

...此外,您可以作爲全局變量需要require.js之前加載,並自動應用該值定義配置對象。

所以我只是改變了我的config.js定義適當配置全球require哈希:

var require = { 
    baseUrl: "/js/libs", 
    paths: { 
     "jquery":  "jquery-1.10.1.min", 
     "knockout":  "knockout-2.2.1", 
     "komapping": "knockout.mapping" 
    } 
}; 

,其中包括它只是前require.js

<script type="text/javascript" src="/js/config.js"></script> 
<script type="text/javascript" src="/js/require.js"></script> 

這種方法允許控制腳本執行順序,所以config.js將總是在下一個require調用之前加載。

所有現在完美的作品。

+2

它將說需求沒有定義 – CodeGuru

+1

謝謝,這個工程,但它在另一個腳本中引起一個小問題,其中讀取:require不是一個函數。 (認爲​​它與變量作用域有關)爲了避免這種情況,可以使用requirejs = {...}而不是require = {...}。似乎做同樣的事情,但沒有問題。另外,您可能需要在模板中創建一個腳本標記來定義一個變量,例如。在config.js中包含並設置「baseUrl:webroot」之前,var webroot ='http:// path/to/webroot',以防止由seo url造成的路由問題。 –

+0

這個解決方案很醜陋,你正在分配一個全局變量,這個變量將在庫聲明後被覆蓋。只需將你的配置放在一個單獨的腳本標記中,緊跟在require.js之後。更多信息:https://github.com/jrburke/requirejs/wiki/Patterns-for-separating-config-from-the-main-module –

2

修復了這個問題。

我的配置是異步加載的,因此配置路徑在我的require語句被調用之前沒有設置。

根據RequireJS文檔Link here,我在require.js調用之前向腳本調用添加了一個腳本調用。並刪除了data-main屬性。

var require = { 
    baseUrl: '/js', 
    paths: { 
     'jquery':  'vendor/jquery/jquery-2.0.3.min', 
     'picker':  'vendor/pickadate/picker.min', 
     'pickadate': 'vendor/pickadate/picker.date.min' 
    }, 
    shim: { 
     'jquery': { 
      exports: '$' 
     }, 
     'picker': ['jquery'], 
     'pickadate': { 
      deps: ['jquery', 'picker'], 
      exports: 'DatePicker' 
     } 
    } 
} 

所有現在工作

+2

非常感謝這一點 - 我遇到了各種與腳本未正確加載有關的問題並永遠找不到答案。 – Valerie