2013-02-12 4 views
8

Ich habe eine Web-App, die im Knoten läuft. Alle (Client-) Javascript/CSS-Dateien sind im Moment nicht minimiert, um das Debuggen zu erleichtern.Skripte/CSS im Produktionsmodus verkleinern mit node.js

Wenn ich in Produktion gehe, möchte ich diese Skripte minimieren. Es wäre schön, etwas zu haben, wie:

node app.js -production

Wie kann ich die verkleinerte Version meiner Skripte dienen, ohne das Script-Tags in meinen HTML-Dateien zu ändern? Es sollte etwas wie Folgendes sein: wenn ich in Produktion bin, benutze diese 2 verkleinerten (kombinierten) Skripte, ansonsten benutze alle meine unminitierten Skripte.

Ist das möglich? Vielleicht denke ich zu kompliziert?

Antwort

15

Das könnte Sie interessieren: Piler. Es ist ein Node.js-Modul, das alle JavaScript- (und CSS-) Dateien liefert, die Sie im Debug-Modus wie gewohnt angeben, im Produktionsmodus jedoch verkettet und minimiert.

Als Besonderheit können Sie CSS-Updates über Socket.io in Echtzeit in Ihrem Browser (in CSS "CSS Live Update" in Piler) erzwingen, was ganz toll ist :-). Der Trick besteht darin, dass innerhalb Ihrer Vorlage nur Platzhalter für die Elemente script und link vorhanden sind, und Piler rendert diese Elemente zur Laufzeit - als einzelne Elemente im Debug-Modus und als dynamisch generiertes Einzelelement im Produktionsmodus.

Auf diese Weise können Sie das Erstellen von verketteten und verkleinerten Versionen Ihrer Assets manuell oder mithilfe eines Build-Tools vergessen, es ist nur zur Laufzeit verfügbar, aber Sie haben beim Entwickeln und Debuggen immer die getrennten Vollversionen.

+0

Danke, das sieht vielversprechend aus .. – Christian

+0

Gern geschehen :-)! –

4

Sie 2 separate Standorte für Ihre statischen Dateien verwenden könnte

Hier einige express Code:

if (process.env.MODE === "production") { 
    app.use(express['static'](__dirname + '/min')); 
} else { 
    app.use(express['static'](__dirname + '/normal')); 
} 

und Startknoten mit

MODE=production node app.js 

Außerdem, wenn Sie nicht wollen Dupliziere alle deine Dateien, du könntest die Tatsache nutzen, dass der Express-Static-Router bei der ersten Datei stoppt, und stattdessen so etwas tun:

if (process.env.MODE === "production") { 
    app.use(express['static'](__dirname + '/min')); // if minized version exists, serves it 
} 
app.use(express['static'](__dirname + '/normal')); // fallback to regular files 

Die Verwendung des gleichen Namens für minimierte oder nicht wird jedoch Probleme mit dem Browser-Caching verursachen.

+0

gut, danke. :-) – Christian

+0

@Pascal, schnelle Frage - schlagen Sie vor, dass die minimierte js-Datei in diesem Ordner vorhanden sein sollte? Wenn dies der Fall ist, müssen Sie es bei jeder Änderung auf Ihrem System erstellen und dann git etc verwenden, um es in die Produktion zu bringen, was nicht als eine sehr gute Idee erscheint. – Tushar

+0

Nein, die minimierte Datei sollte normalerweise nicht in Git gespeichert werden. Entweder der Server selbst oder etwas wie 'grunt' kann auf dem Produktionsserver verwendet werden, um die verkleinerte Version zu erzeugen. –

1

Ich möchte meine endgültige Lösung mit euch teilen.

I JSHTML für Express verwenden (enter link description here)

In meinem Hauptknoten Datei verwende ich eine spezielle Route:

app.get('/**:type(html)', function (req, res, next) { 
var renderingUrl = req.url.substring(1, req.url.lastIndexOf(".")); 
//TODO: Find a better solution 
    try{ 
     var assetUrl = req.url.substring(req.url.lastIndexOf("/") + 1, req.url.lastIndexOf(".")); 
     var assets = config.getResourceBundle(assetUrl); 
     assets.production = config.getEnviroment() === "production"; 
     res.locals(assets); 
     res.render(renderingUrl); 
    }catch(e){ 
     res.redirect("/"); 
    } 
}); 

Wie Sie sehen können, habe ich mein Vermögen von config.getResourceBundle bekommen.Dies ist eine einfach Funktion:

exports.getResourceBundle = function(identifier){ 
    switch(enviroment){ 
     case "development": 
      return devConfig.getResourceBundle(identifier); 
     case "production": 
      return prodConfig.getResourceBundle(identifier); 
     default: 
      return devConfig.getResourceBundle(identifier); 
    } 
} 

Und schließlich ein Beispiel für eine Dateisammlung Vermögenswert ist hier:

exports.getResourceBundle = function (identifier) { 
    return resourceBundle[identifier]; 
}; 


resourceBundle = { 
    index:{ 
     cssFiles:[ 
      "resources/dev/css/login.css", 
      "resources/dev/css/logonDlg.css", 
      "resources/dev/css/footer.css" 
     ], 
     jsFiles:[ 
      "resources/dev/js/lib/jquery/jquery.183.js", 
      "resources/dev/js/utilities.js", 
      "resources/dev/js/lib/crypto.3.1.2.js" 
     ] 
    }, 
    register:{ 
     cssFiles:[ 
      "resources/dev/css/login.css", 
      "resources/dev/css/modalDialog.css", 
      "resources/dev/css/footer.css" 
     ], 
     jsFiles:[ 
      "resources/dev/js/lib/jquery/jquery.183.js", 
      "resources/dev/js/utilities.js", 
      "resources/dev/js/lib/crypto.3.1.2.js", 
      "resources/dev/js/lib/jquery.simplemodal.js", 
      "resources/dev/js/xfiles.register.js" 
     ] 
    } 
(...) 

Ich habe 2 Ordner. Entwickler/Hersteller Grunt kopiert die verkleinerten Dateien in prod/.. und löscht die Dateien von dev/... Und wenn die Variable NODE_ENV auf production gesetzt ist, werde ich die verkleinerten Versionen meiner Skripte/css versenden. Ich denke, das ist die eleganteste Lösung im Moment.

0

Ein weiteres Node.js-Modul, das sein könnte relevant ist connect-cachify.

Es scheint nicht, für Sie die tatsächliche minification zu tun, aber es funktioniert können Sie die verkleinerte Version in der Produktion dienen, oder alle ursprünglichen Skripte in der Entwicklung, ohne die Vorlagen (dank cachify_js und cachify_css) zu verändern.

Scheint, es ist nicht so funktionsreich wie Piler, aber wahrscheinlich ein bisschen einfacher, und sollte alle in der Frage genannten Anforderungen erfüllen.