2014-02-25 12 views
5

Meine Seite enthält mehrere Komponenten, die als separate AMD-Module existieren. Jede dieser Komponenten wird vom Require.js-Optimierer in eine einzige Datei umgewandelt. Da mehrere dieser Komponenten Abhängigkeiten gemeinsam haben (z. B. jQuery und d3), verwendet die Optimiererkonfiguration paths CDN-URLs für diese Abhängigkeiten, anstatt sie in der optimierten Datei zu bündeln.Wie kann ich eine lokale Datei während der Require.js-Optimierung verwenden, aber eine CDN-gehostete Version zur Laufzeit?

Hier wird es knifflig. Ich habe eine module loader plugin für Ractive.js namens rvc.js geschrieben, die es mir erlaubt, in HTML-Dateien definierte ractive Komponenten einzuschließen. (Ja, ich um Hilfe zu bitten, wie meine eigene Bibliothek verwenden.)

Dies funktioniert gut - Code wie folgt optimiert wird, wie man es erwarten würde:

define(function (require) { 
    var ChartView = require('rvc!views/Chart'); 
    var view = new ChartView({ el: 'chart' }); 
}); 

Da Ractive wird von mehreren verwendet von den Komponenten sollte es von einem CDN wie jQuery und d3 serviert werden. Aber es wird von rvc.js während des Optimierungsprozesses verwendet, was bedeutet, dass der Eintrag Ractive für die paths Konfiguration des Optimierers nicht auf ein CDN zeigen kann - er muss auf eine lokale Datei zeigen.

Gibt es eine Möglichkeit zu sagen, dass Require.js die lokale Datei während der Optimierung verwendet, aber zur Laufzeit von CDN geladen wird?

+0

setzen eine var wie fileToUse = amILocal()? "lib.js": "lib.min.js"; und übergeben Sie FileToUse anstelle eines fest codierten Literals. – dandavis

+0

Das Problem ist, dass der Wert von "fileToUse" dem Optimierer übergeben wird. Dies ist a) die Datei, die während der Optimierung verwendet wird und b) die Datei, die der Optimierer im Build enthält (oder versucht). Wenn also "fileToUse" lokal ist, wird die lokale Datei von rvc.js während der Optimierung verwendet, aber sie wird auch gebündelt; Wenn es entfernt ist, schlägt die Optimierung fehl. –

Antwort

4

Also hier ist die Lösung, die ich schließlich beschlossen hat. Es fühlt sich etwas kludgy, aber es funktioniert:

  1. Stub aus den Lader und die Bibliothek, die Sie nicht wollen, gebündelt
  2. eine onBuildWrite Funktion hinzufügen, die Module auf der Bibliothek abhängig umschreibt, so dass sie denken, sie sind etwas ganz anderes erfordert - in diesem Fall Ractive_RUNTIME
  3. der Fügen Sie einen Eintrag auf Ihre Laufzeit AMD Config paths Objekt, so dass Ractive_RUNTIME Punkte auf dem CDN

Meine optimiser Config jetzt wie folgt aussieht:

{ 
    baseUrl: 'path/to/js/', 
    out: 'build/js/app.js', 
    name: 'app', 
    optimize: 'none', 

    paths: { 
    'amd-loader': 'loaders/amd-loader', 
    'rvc': 'loaders/rvc', 
    'Ractive': 'lib/Ractive' 
    }, 

    stubModules: [ 'amd-loader', 'rvc', 'Ractive' ], 

    onBuildWrite: function (name, path, contents) { 
    if (contents === "define('Ractive',{});") { 
     // this is the stub module, we can kill it 
     return ''; 
    } 

    // otherwise all references to `Ractive` need replacing 
    return contents.replace(/['"]Ractive['"]/g, '"Ractive_RUNTIME"'); 
    } 
} 

Inzwischen hat die Skript, das die app.js Datei vom Optimiser erstellt lädt hat eine Config-Eintrag, der auf dem CDN-Punkte:

require.config({ 
    context: uniqueContext, 
    baseUrl: baseUrl, 

    paths: { 
    'amd-loader': 'loaders/amd-loader', 
    'rvc': 'loaders/rvc', 
    'Ractive': 'lib/Ractive', 
    'Ractive_RUNTIME': 'http://cdn.ractivejs.org/releases/0.3.9/Ractive.min' 
    } 
});