2012-11-26 83 views
2

是否可以在運行時修改requirejs(或任何AMD加載程序)配置?在運行時配置RequireJS

作爲一個例子,我有兩個日誌模塊:一個簡單地包裝console.log和其他日誌到服務器。我希望模塊只需要登錄(require(['log'], function(log) { ... });)而不關心它使用的記錄器。

我可以在需要的主配置中將'log'設置爲一個包,並且工作正常。但是我想要做的就是在幾個條件的基礎上在main.js中設置這個選項。例如:

if(...) { 
    require.config({ 
     packages: [ 
      { name: 'log', location: 'app/base/utils/consolelog' } 
     ] 
    }); 
} 

但是,這似乎並不奏效。有沒有辦法做到這一點,或者我是否將requirejs的功能作爲依賴注入框架?

乾杯

+1

它究竟不工作?當你移除「if」時會發生什麼?應該可以在運行時像這樣配置requireJS,只要在需要配置完成之前完成任何依賴關係。 – EMMERICH

回答

3

任何依賴注入框架的通用儀器是,你有一個簡單的方法來配置它在運行時會解決什麼樣的依賴容器,它是構建只有一次通過的壽命保持靜態應用程序。

這樣做的具體做法是,您不會陷入這樣的情況,即依賴關係可能會在應用程序中的某個位置發生更改。有了這樣一個觀念,即一個或所有應用程序源可能需要在容器消耗一些或任何依賴項之前請求權限,而不是僅僅對容器執行nom操作,這是一個糟糕的想法,它有很多缺點。主要缺點是,您知道,accounts.all().each().withdraw(billing.MONTHLY_SERVICE_FEE).return()中的任何參考文獻在任何情況下都可能因爲沒有明顯原因而表現不同。如果Accounts改變,new Accounts().all()沒有返回任何帳戶,或者如果billing.MONTHLY_SERVICE_FEE改變了突然的一切,你收取一些賬戶的X量和其他與Y.

所以這將是糟糕的,簡單的答案是否定的,你不能動態配置RequireJS。 RequireJS將始終只加載一次模塊,因此回調函數的返回值始終是一個靜態對象,或者如果您願意,當您查看模塊來源時,您知道它的define()將僅在生命週期中評估一次該文件。

對於如何在運行時抽象對象的特定實現,有幾個非常簡單的方法。您只需使用回調創建幾個模塊,該模塊將返回具有相同公共接口的對象,但具有不同的行爲,然後您可以靜態或動態地解析返回的對象。

// core/logging/base.js 
define(function() { 
    var static; 
    var base = { 
     _log: undefined, 
     create: function(name) {}, 
     // .. 
    } 

    return base; 
}); 

// core/logging/client.js 
define(function(['core/logging/base'], function(base) { 
    var client = extend(base, {_log: console.log}); 
    return client; 
}); 

// core/logging.js 
define(['core/logging/server', 'core/logging/client', 'core/conf/settings'], 
    function(server, client, environment) { 
    if(settings.LOGGER === 'server') { 
    return server; 
    } else { 
    return client; 
    } 
}; 

// app/foo.js 
define(['core/logging'], function(logging) { 
    var log = logging.createLog('foo'); 
    log.info('bar'); 
    // > INFO foo: bar 
    // or... 
    // POST http://server/log {type: 2, name: 'foo', message: 'bar'} 
} 

有幾種方法可以設計出這樣的支持,但是這種方法很簡單,適用於您的特殊情況。通常,您可以在模塊中靜態執行此分辨率,也可以通過getter函數在任何塊中動態執行此分辨率,模塊回調函數本身也可以返回構造函數或函數,而不僅僅是對象。