2012-10-16 13 views
14

Das ist das erste Mal, dass ich Grunt benutze und ich möchte, dass es alle meine js-Module kombiniert, von denen jedes in einer sofort ausführenden Funktion verpackt ist. enthält eine "use strict" -Deklaration und fügt sie in eine Datei ein, die in nur einer unmittelbar ausführenden Funktion verpackt ist, mit nur einer "use strict" -Deklaration.Ich probiere Grunt aus und brauche eine einfache Methode, um meine Module zu verketten.

Wie wird das normalerweise gemacht?

Ich dachte, das wäre ein häufiger Anwendungsfall? Vielleicht gehe ich die Dinge falsch an? Sollte ich eines der Module Ladeformate verwenden (d. H. Commonjs, amd) Alle diese Dateien werden immer zusammen in den Browser geladen, so dass ich eigentlich nichts dagegen hätte, alle sofort ausführenden Funktionen zu entfernen, wenn die Leute normalerweise so darüber gehen. Der wichtige Teil ist, dass das Endergebnis irgendwie verpackt ist, besteht aus Flusen und Unit Tests und enthält die 'Use Strict' Deklaration.

(Ich sollte klarstellen, ich habe es funktioniert, linting, Komponententests, Verkettung und Minifying, es fühlt sich einfach an, als würde ich etwas falsch machen, wenn ich eine Reihe von unnötigen sofort ausgeführten Funktionen in der endgültigen verkettet sehen Datei.)

Antwort

22

Normalerweise mache ich es wie die jQuery team does it. Sie erstellen eine intro.js und outro.js und zwischen setzen alles andere in:

intro.js

;(function(window, undefined){ 
    'use strict'; 

outro.js

}(window)); 

grunt.js:

concat: { 
    dist: { 
    src: [ 
     'js/src/intro.js', 
     ... 
     'js/src/outro.js' 
    ], 
    dest: 'js/out/app.js' 
    } 
} 
+0

verdammt, ich selbst an ihrem GitHub Repo sah zu sehen, wie sie es taten, aber total nicht versteht, dass dank! – uglymunky

+1

Ich benutze tatsächlich grunt, um dies mit meinem statischen HTML während der Entwicklung zu tun. Und ich habe das gleiche mit js gemacht, aber statt intro/outro benutze ich Kopf und Fuß. Da ich Doc-Titel während der Entwicklung nicht dynamisch aktualisieren muss, funktioniert es großartig. – jonschlinkert

2

Sie möchten nur zu @elclanrs antworten, wenn Sie in der Lage sein möchten, Ihre Module in separaten Dateien für das Debuggen während der Entwicklung zu halten, müssten Sie sie natürlich auch mit intro.js und outro.js umhüllen. Mit den eingebauten in concat Aufgabe, die Sie so etwas wie schreiben müßten:

concat: { 
    events_debug: { // wrap the 'events' module in IIFE 
    src: [ 
     'js/src/intro.js', 
     'js/src/events.js', 
     'js/src/outro.js' 
    ], 
    dest: 'js/out/events.js' 
    }, 
    callbacks_debug: { // wrap the 'callbacks' module in IIFE 
    src: [ 
     'js/src/intro.js', 
     'js/src/callbacks.js', 
     'js/src/outro.js' 
    ], 
    dest: 'js/out/callbacks.js' 
    } 

    // zzZZZ... 
} 

, die sehr mühsam und Selbstwiederholungs ist. Vielleicht möchten Sie eine benutzerdefinierte Aufgabe für das Mass-Wrapping von Dateien erstellen, z.

wrap: { 
    html: { 
     intro: 'partials/intro.js', 
     outro: 'partials/outro.js', 
     src: 'js/*.js', 
     dest: 'out' // output directory 
    } 
} 

Es eine Frage zu diesem vor kurzem war, finden Sie in diesem Thread:

Using grunt concat, how would I automate the concatenation of the same file to many other files?

+1

Danke @Dmitry, ich denke ich bekomme langsam, wie das funktioniert, es ist nicht sehr geradlinig. Ich frage mich, ob es sinnvoller ist, jedes Modul zu schreiben, das in einem Leben steckt, und dann eine Grunt-Aufgabe zu haben, die den Wrapper entkleidet. Wie vielleicht strippt es alles vor einem '// <- intro' und alles nach einem' // outro -> '...? – uglymunky

+0

... Ich denke, "Wrap" anstelle von "Unwrap" zu tun haftet besser auf "DRY" – uglymunky

+0

Es liegt an Ihnen :) Natürlich ist Verketten einfacher und sicherer und schneller als ein Muster zu strippen. Aber andererseits bin ich mir nicht sicher, ob meine Quelldateien vom Build-Tool abhängen (dh, Ihre Module sind nicht mehr portierbar, weil sie nicht funktionieren, ohne in IIFE verpackt zu sein. Auf der anderen Seite werden Sie müssen Sie IIFE manuell von allen externen Modulen entfernen, die Sie in Ihr Projekt aufnehmen). So gute Überlegungen ... –

34

Ab pull request 10, grunzen-contrib-concat hat jetzt eine footer Option. Statt einer Intro- und einer Outro-Datei würde ich ein Banner und ein Fußzeile verwenden.

Gruntfile.js

concat: { 
    dist: { 
    src: ['src/my-lib.js'], 
    dest: 'dist/<%= pkg.name %>.js', 
    options: { 
     banner: ";(function(window, undefined){ \n 'use strict';", 
     footer: "}(window));" 
    } 
    } 
} 

Meiner Meinung nach ist dies besser verwaltbar ist und ermöglicht Templating andere Eigenschaften in Ihrem Gruntfile definiert ist.

+0

Zustimmen, das ist weit besser als jede andere Option und da ist die offizielle Grunt-Version, können Sie sicher sein, dass Das Plugin wird beibehalten. – Rodrigo

1

Ich würde Ihnen empfehlen, mein grunt Plugin grunt-concat-deps zu verwenden, da es automatisch Ihre Module unabhängig von Ihrer Architektur auflöst.

PLUS: Sie benötigen keine explizite Modulkonfiguration für das Plugin, da es auf der deklarativen und dezentralen Moduldefinition in einem YUIDoc-Stil beruht.

Sehen Sie hier für weitere Informationen: https://github.com/leoselig/grunt-concat-deps