2013-06-11 12 views
13

Jestem programistą JavaScript i całkiem nowym do tworzenia procesu budowania od zera. Zdecydowałem się użyć Grunta do mojego obecnego projektu i stworzyłem GruntFile, który zajmuje około 90% tego, co jest mi potrzebne i działa świetnie, z wyjątkiem tego jednego problemu. Mam kilka plików JavaScript, które odwołuję się podczas rozwijania rozszerzenia chrome w pliku manifest.json. Dla mojego procesu kompilacji łączę wszystkie te pliki i zamieniam je w jeden plik, który ma być zawarty w manifest.json. Czy istnieje mimo to aktualizacja odniesień do plików w pliku manifest.json podczas procesu kompilacji, aby wskazywała na wersję minified?Aktualizowanie odniesień do plików w pliku json za pomocą zadania pomruczania

Oto fragment pliku manifestu src:

{ 
    "content_scripts": [{ 
     "matches": [ 
      "http://*/*" 
     ], 
     "js": [ 
      "js/lib/zepto.js", 
      "js/injection.js", 
      "js/plugins/plugin1.js", 
      "js/plugins/plugin2.js", 
      "js/plugins/plugin3.js", 
      "js/injection-init.js" 
     ] 
    }], 
    "version": "2.0", 
} 

mam zadanie grunt że skleja i minifies wszystkie pliki js wymienione powyżej w jeden plik o nazwie injection.js i chciałby zadanie grunt, że można zmodyfikować manifest file więc wygląda to tak:

{ 
    "content_scripts": [{ 
     "matches": [ 
      "http://*/*" 
     ], 
     "js": [ 
      "js/injection.js" 
     ] 
    }], 
    "version": "2.0", 
} 

Co robiłem na razie jest mieć 2 wersje pliku manifestu, po jednym dla dev i jeden dla produkcji, w trakcie procesu kopiuje wersji build build zamiast . Oznacza to, że muszę utrzymywać 2 wersje, których wolałbym nie robić. Czy istnieje jeszcze sposób, aby to zrobić bardziej elegancko z Gruntem?

Odpowiedz

26

Grunt daje własne API do odczytu i zapisu plików, czuję, że lepiej niż inne zależności jak fs: Edycja pliku/Aktualizacja json używając chrząknięcie z poleceniem grunt updatejson:key:value po oddaniu tego zadania w pliku gruntjs

grunt.registerTask('updatejson', function (key, value) { 
     var projectFile = "path/to/json/file"; 


     if (!grunt.file.exists(projectFile)) { 
      grunt.log.error("file " + projectFile + " not found"); 
      return true;//return false to abort the execution 
     } 
     var project = grunt.file.readJSON(projectFile);//get file as json object 

     project[key]= value;//edit the value of json object, you can also use projec.key if you know what you are updating 

     grunt.file.write(projectFile, JSON.stringify(project, null, 2));//serialize it back to file 

    }); 
+0

również nie jest 'grunt.file.readYAML', spróbuj http://gruntjs.com/api/grunt.file dla informacji – tekkavi

+0

Właśnie zauważyłem ten komentarz, dziękuję, to dobrze wiedzieć. Od tego czasu zacząłem używać przeglądarki, co negatywnie wpłynęło na to, że zacząłem ten wątek w pierwszej kolejności ... jednak wciąż czytam/zapisuję pliki w chmurze używając fs z innych powodów i jest to naprawdę pomocne. – Charles

11

Ja robię coś podobnego - możesz załadować swój manifest, zaktualizować zawartość, a następnie ponownie go serializować. Coś jak:

grunt.registerTask('fixmanifest', function() { 
    var tmpPkg = require('./path/to/manifest/manifest.json'); 

    tmpPkg.foo = "bar"; 
    fs.writeFileSync('./new/path/to/manifest.json', JSON.stringify(tmpPkg,null,2)); 
}); 
0

Nie zgadzam się z innymi odpowiedziami tutaj.

1) Dlaczego warto używać grunt.file.write zamiast fs? grunt.file.write to tylko opakowanie dlafs.writeFilySync (patrz kod here).

2) Po co używać fs.writeFileSync, gdy grunt sprawia, że ​​jest bardzo łatwy w obsłudze, aby można było wykonywać asynchroniczne operacje? Nie ma wątpliwości, że nie musisz potrzebować asynchronizacji w procesie kompilacji, ale jeśli jest to łatwe, dlaczego nie byłbyś? (. Jest to w rzeczywistości tylko kilka znaków dłuższe niż realizacja writeFileSync)

Chciałbym zaproponować następujące:

var fs = require('fs'); 
grunt.registerTask('writeManifest', 'Updates the project manifest', function() { 
    var manifest = require('./path/to/manifest'); // .json not necessary with require 
    manifest.fileReference = '/new/file/location'; 
    // Calling this.async() returns an async callback and tells grunt that your 
    // task is asynchronous, and that it should wait till the callback is called 
    fs.writeFile('./path/to/manifest.json', JSON.stringify(manifest, null, 2), this.async()); 

    // Note that "require" loads files relative to __dirname, while fs 
    // is relative to process.cwd(). It's easy to get burned by that. 
}); 
+0

Właściwie 'require()' jest synchronicznym FS, więc twoje zadanie nie jest w rzeczywistości całkowicie asynchroniczne. –

+0

Po pierwsze, nie powiedziałem, że tak. Właśnie sugerowałem 'fs.writeFile' jako alternatywę (czytaj: poprawa) do' grunt.file.write'.Inne rozwiązania również "wymagają" pliku json, więc to wciąż jest poprawa. Jeśli naprawdę zależy Ci na wykonaniu całego asynchronicznego zadania, możesz albo "fs.readFile" json zamanifestować, albo przenieść wymaganie poza samym zadaniem (tj. Gdzie 'fs' jest wymagane), ponieważ sam zbiór zadań jest synchroniczny (to przy założeniu oczywiście, że manifest nie zmienia się między ładowaniem zadania a uruchomieniem zadania). – tandrewnichols

+0

Innym ulepszeniem, które zasugerowałbym całkiem powszechnie z zadaniami typu "grunt" jest użycie 'fs-extra' zamiast' fs' i użycie takich metod jak 'outputFile', które spowodują' mkdir -p' na brakujących ścieżkach katalogów. – tandrewnichols

Powiązane problemy