2013-05-28 15 views
38

Ich bin neu in Grunt, und bis jetzt genieße ich es sehr. Ich will Grunt kompilieren nur die geänderten Dateien beim AusführenGrunt: Watch mehrere Dateien, Kompilieren nur geändert

In meinem Grunfile.coffee habe ich derzeit (relevante Teile).
Hinweis: assets/javascript/app.coffee und Vermögen/javascript/app.js sind Verzeichnisse

coffee: 
     default: 
      expand: true 
      cwd: "assets/javascript/app.coffee" 
      src: ["*.coffee"] 
      dest: "assets/javascript/app.js" 
      ext: ".js" 

    uglify: 
     dev: 
      options: 
       beautify: true 
       compress: false 
       mangle: false 
       preserveComments: 'all' 

      files: 
       "js/app.js": "assets/javascript/app.js/*.js" 
       "js/libs.js": "assets/javascript/libs/*.js" 

    watch: 
     coffeescript: 
      files: 'assets/javascript/**/*.coffee' 
      tasks: ["coffee"] 

     javascript: 
      files: "assets/**/*.js" 
      tasks: ["uglify:dev"] 
     livereload: 
      files: ["Gruntfile.coffee", "js/*.js", "*.php", "css/*.css", "images/**/*.{png,jpg,jpeg,gif,webp,svg}", "js/*.js", ] 
      options: 
       livereload: true 

Es um wahrscheinlich ein kürzerer Weg ist, aber ich bin app.coffee zu app.js Kompilieren Erstens, damit ich, nachdem ich meine Arbeit verteilt habe, Leute, die sich mit Coffeescript nicht auskennen, den Code einigermaßen vernünftig durchsuchen können.

Das Problem dabei alles, was jetzt ist, dass ich einen Coffeescript-Datei speichern, ich zu viele Schritte erhalten (glaube ich):

>> File "assets/javascript/app.coffee/browse.coffee" changed. 

Running "coffee:default" (coffee) task 
File assets/javascript/app.js/browse.js created. 
File assets/javascript/app.js/filters.js created. 

Done, without errors. 
Completed in 0.837s at Tue May 28 2013 12:30:18 GMT+0300 (EEST) - Waiting... 
OK 
>> File "assets/javascript/app.js/browse.js" changed. 
>> File "assets/javascript/app.js/filters.js" changed. 

Running "uglify:dev" (uglify) task 
File "js/app.js" created. 
File "js/libs.js" created. 

Done, without errors. 
Completed in 0.831s at Tue May 28 2013 12:30:19 GMT+0300 (EEST) - Waiting... 
OK 
>> File "js/app.js" changed. 
>> File "js/libs.js" changed. 

Completed in 0.000s at Tue May 28 2013 12:30:19 GMT+0300 (EEST) - Waiting... 

Derzeit habe die Einrichtung ich nur mein Projekt, aber ich werde viel mehr Coffeescript-Dateien, und ich möchte nicht, dass Coffeescript alle Dateien bei jeder Dateiänderung neu kompiliert.

Darüber hinaus hat libs.js überhaupt keinen Teil davon, aber ich denke, es ist immer noch kompiliert, weil es auch mit dem Muster "assets/* / .js" übereinstimmt.

Gibt es eine Möglichkeit, Grunt kompilieren nur die Dateien, die geändert haben?

+1

möglich Duplikat von [Wie sehen Sie mehrere Dateien, aber nur Task auf geänderte Datei in Grunt.js ausführen?] (Http://stackoverflow.com/questions/12063266/how-do-you-watch- multiple-files-but-only-run-task-on-changed-file-in-grunt-js) –

Antwort

69

ich eine echte Lösung gefunden haben, endlich! Und es ist auch super einfach!

npm install grunt-newer --save-dev

Dann in Ihrem Gruntfile (nach der Aufgabe in Grunzen Laden):

watch: 
    coffeescript: 
     files: 'assets/javascript/**/*.coffee' 
     tasks: ["newer:coffee"] 

Und das ist es! The Awesome grunt-newer is awesome!

+1

Schön - genau das habe ich gebraucht! Ich musste nicht einmal irgendwelche Dokumente oder Anweisungen lesen - es funktioniert einfach. –

+0

Yay! perfekt! Danke für dieses Juwel :) – flks

+0

Einfach genial^_^ –

2

Wenn Sie alle .coffee-Quellen in eine .js-Datei einschließen, müssen Sie sie jedes Mal erneut kompilieren, wenn sich eine Ihrer Quellen ändert. Teilen Sie es in mehrere .js-Dateien und machen Sie eine Version Aufgabe, wo Sie nur diese .js-Dateien concat. Auf diese Weise müssen Sie nur noch eine .js-Datei hinzufügen.

Siehe Using gruntjs, how do watch for changes in .coffee files?

+0

Das ist die Sache. Ich kompiliere jede Coffeescript-Datei in eine separate JavaScript-Datei, sodass der Compiler die andere coffeescript-Datei nicht wirklich anfassen sollte. Die Javascript-Dateien werden dann in app.js verkettet, aber das ist eine separate Aufgabe, die auch versehentlich das Komprimieren von libs.js aufruft, was ebenfalls unnötig ist. – Norris

+0

Dann einfach einfach lib.js von der Uhr mit "! Js/libs.js" ausschließen. Vielleicht kannst du deinen eigenen [Benutzerdefinierten Filter] (http://gruntjs.com/configuring-tasks#custom-filter-function) schreiben oder nach einem [ähnlichen Feature] fragen (https://github.com/gruntjs/grunt- contrib-copy/pull/56). – Jamesgt

+0

Das war eigentlich die vernünftigste Lösung, ich bleibe dabei, bis ich etwas Besseres finde ... – Norris

1

Das grunt.event.on Ereignis Änderungen in Dateien erkennt, ein action und filepath Parameter zu empfangen.

Hier ist ein ungetestetes Beispiel basierend auf einer meiner Gruntfiles. In diesem Fall sind alle meine Quelle Coffeescript-Dateien werden in einem Verzeichnis namens Quellen gehalten, und für die Vorschau sie zusammengestellt und dev

SOURCES_DIR = 'sources' 
DEV_DIR = 'dev' 

grunt.initConfig 
    watch : 
    all : 
     files : ["**/*.coffee"] 
    coffee : 
    dev : 
     files : 
     dest : "app.js" 
grunt.loadNpmTasks 'grunt-contrib-watch' 
grunt.loadNpmTasks 'grunt-contrib-coffee' 

grunt.registerTask 'build', ['coffee:dev'] 

grunt.event.on('watch', (action,filepath) -> 
    # Determine the full directory of the changed file 
    wdi = filepath.lastIndexOf '/' 
    wd = filepath.substring 0,wdi 

    # remove `sources` prefix from that directory 
    fpath = wd.replace(SOURCES_DIR,'') + '/' 

    # determine the filename 
    fnamei = filepath.lastIndexOf '.' 
    fname = filepath.substring wdi+1,fnamei # NOTE: this breaks the case where in same dir 

    # concatenate fpath and fname with the dir to be compiled into 
    deststr = "#{DEV_DIR}#{fpath}#{fname}.coffee" 


    # set coffee.dev.files value in the coffee task to have am entry of form {"destination":"source"} 
    obj = {} 
    obj[deststr] = filepath 
    grunt.config "coffee.dev.files", obj 

    # fire the coffee task 
    grunt.task.run "coffee" 
) 

Hoffnung auf eine identische Verzeichnisstruktur unter einem Verzeichnis mit dem Namen gespeichert, das hilft.

EDIT: Wahrscheinlich nicht genau das, was Sie wollen - denn ohne Zweifel wollen Sie Zugriff auf intermediäre Variablen, Aktionen und so weiter - aber Sie könnten grunt verwenden, um nur einen Shell-Kaffee-Befehl auszuführen. Die grunt-shell npm Aufgabe tut dies zum Beispiel

EDIT2: Ich habe weiterhin Probleme konfrontiert mit grunt.watch.on nicht konsequent in Grunzen 0.4.1 auf OSX 10.8 und MacVim 7.3 arbeiten; aus welchem ​​Grund auch immer hört es auf zu beobachten. Ich habe wieder auf das einfache grunt-initConfig-Objekt zurückgegriffen, aber mit viel mehr Granularität, so dass es nur relativ kleine Gruppen von Dateien beobachtet und kompiliert anstatt die ganze Menge. Dies verlangsamt die Aufbauzeit erheblich, ist aber wesentlich robuster. Ihre Laufleistung kann sehr.

+0

Danke, das sieht tatsächlich nach etwas aus, nach dem ich gesucht habe. Ich werde es mir später genauer ansehen. – Norris

0

Auch ich bin darüber gestolpert und habe keine funktionierenden Versionen gefunden, die mit der aktuellen Version (0.4.1) funktionierten. Aber die Antwort von Joof Arnolds zeigte einen guten Ansatz.

Dies ist, was ich kam mit:

# only recompile changed files 
grunt.event.on "watch", (action, filepath) -> 
    # note that we have to manually change the target file name to 
    # our desired format 
    targetName = filepath.replace(/\/(client|shared)/, "") 
    .replace(".coffee", ".js") 
    .replace("app/", "") 

    options = 
    src: filepath 
    dest: "public/javascripts/#{targetName}" 

    grunt.config ["coffee", "client"], options 

ich einen Kaffee Schnitt haben, der etwas sieht wie folgt aus:

coffee: 
    client: 
    options: 
     sourceMap: false 
    files: [ 
     expand: true 
     cwd: "app" 
     src: ["*/client/**/*.coffee", "helpers/{client,shared}/*.coffee"] 
     dest: "public/javascripts" 
     rename: (folder, name) -> 
     name = name.replace(/\/(client|shared)/, "") 

     [folder, name].join path.sep 
     ext: ".js" 
    ] 
Verwandte Themen