2012-08-22 16 views
29

Nella mia app per backbone, è necessario fornire un fallback per ciascun file richiesto, nel caso in cui il CDN che li consegna non riesca.RequireJS: fallback locale per il fallimento del CDN

ho cercato di sovrascrivere require.onError in questo modo:

require.onError = function (err) { 
    if (err.requireType === 'timeout') { 
     var url = err.requireModules; 

     if (!!~url.indexOf("jquery/")) 
      console.warn("CDN timed out, falling back to local jQuery.js") 
      require(["libs/jquery"]); 
      return; 
     if (!!~url.indexOf("jqueryui/")) 
      console.warn("CDN timed out, falling back to local jQueryUI.js") 
      require(["libs/jqueryui"]); 
      return; 
     if (!!~url.indexOf("underscore")) 
      console.warn("CDN timed out, falling back to local underscore.js") 
      require(["libs/underscore"]); 
      return; 
     if (!!~url.indexOf("backbone")) 
      console.warn("CDN timed out, falling back to local backbone.js") 
      require(["libs/backbone"]); 
      return; 
    } 
} 

Il problema è che questo modo asincrono caricare i file di fallback. Ho bisogno che questi file vengano caricati in ordine, proprio come nella richiesta originale, dove uso il plugin order!.

Con l'override onError: quando il CDN non riesce a caricare, il caricamento fallback viene avviato, ma non è atteso. Questo presenta un problema perché gli script sono ordinati per essere caricati in base alle loro dipendenze. Ecco uno sguardo al mio require dichiarazione originale, che dipende dalla CDN:

require([ 
    "order!http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js", 
    "order!http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js", 
    "order!http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js", 
    "order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js", 
    "order!utils/date", 
    "order!core/core", 
    "order!core/errors", 
    "order!core/constants" 
], function() { 
    ... 
} 
+0

Entrambi CDN di non sono terribili, non solo non riescono, in media, una volta al giorno per una finestra di circa un minuto al massimo, e sono gratuiti. Indipendentemente da ciò, ritengo che questo sia un problema interessante da risolvere. Sempre buono avere fallback anche se si dispone di un CDN perfetto, per preservare l'esperienza dell'utente. Puoi suggerire altri CDN? – Austin

+0

Capisco da dove vieni, ma non sono nella posizione di suggerire l'acquisto di qualcosa di simile per la nostra azienda senza fornire un'ampia prova che ho provato di tutto per far funzionare il sistema attuale. Inoltre, sono interessato a qualsiasi impresa di programmazione, e posso vedere questa particolare soluzione essere utile a molte persone, dal momento che molti sviluppatori (freelance in particolare) non utilizzano CDN a pagamento. – Austin

+1

CDN è molto economico ora (da $ 2 a $ 3 al mese) ... Sto usando AccuWebHosting.Com CDN e non ho mai avuto alcun tempo morto. Bene, se un server fallisce in CDN, il contenuto viene immediatamente consegnato dal POP successivo disponibile più vicino ... E ci sono solitamente da 40 a 50 POP in un buon CDN ... –

risposta

57

Quale versione di RequireJS stai usando? Sembra che potresti voler configurare il fallback di jQuery come percorso nella tua configurazione, quindi configurare jQuery come dipendenza dagli altri moduli che ne hanno bisogno. Se stai usando ~> 2.0, qualcosa di simile (non testata):

// in your requirejs config 
requirejs.config({ 
    //To get timely, correct error triggers in IE, force a define/shim exports 
    // check. 
    enforceDefine: true, 
    paths: { 
     jquery: [ 
      'http://somecdn.com/jquery.min', // your cdn 
      'lib/jquery' // your fallback 
     ], 
     jqueryui: "http://somecdn.com/jquery-ui.min.js" 
    }, 
    shim: { 
     jqueryui: ['jquery'] 
    } 
}); 

// then in your requires 
require([jquery, jqueryui, foo, bar], function($) { 
    // stuff 
}); 

Parlano di come farlo in the wiki. Se non stai usando v2.x, c'è un metodo per gestirlo anche qui.

Se tutti i moduli sono configurati per specificare le proprie dipendenze, non è necessario preoccuparsi delle direttive order!.

+0

Picchiami al palo di 2 minuti, ma sì, questa è la risposta che ho seguito. – Austin

+0

Haha nemmeno. Penso che sia stato circa 15 secondi. – numbers1311407

+2

Come viene gestita una volta eseguito l'ottimizzatore? Aggiunge tag di script all'html per i file esclusi? – sidonaldson

19

Ho trovato una soluzione al problema fornito in RequireJS 2.x.x. C'era una richiesta per questa soluzione, quindi a sua volta RequireJS ha aggiunto un oggetto paths alla propria configurazione. Ciò fornisce funzionalità di fallback per i CDN, nel caso in cui falliscano.

Si noti inoltre che il plug-in order! è stato deprecato in Require 2.0, quindi ho anche dovuto utilizzare l'oggetto shim per definire le dipendenze. In realtà è un'idea piuttosto interessante.

Ecco il mio nuovo require.config:

require.config({ 
    urlArgs: "ts="+new Date().getTime(), // disable caching - remove in production 
    paths: { 
     jquery: [ 
      "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min", 
      "libs/jquery" 
     ], 
     jqueryui: [ 
      "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min", 
      "libs/jqueryui" 
     ], 
     underscore: [ 
      "http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min", 
      "libs/underscore" 
     ], 
     backbone: [ 
      "http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min", 
      "libs/backbone" 
     ] 
    }, 
    shim: { 
     'jqueryui': ['jquery'], 
     'underscore': ['jquery'], 
     'backbone': ['underscore'], 
     'core/core': ['underscore'], 
     'core/errors': ['core/core'], 
     'core/constants': ['core/core'] 
    } 
}); 
Problemi correlati