2013-06-11 12 views
13

私はJavaScript開発者であり、ビルドプロセスを最初から作成するのはかなり新しいです。 Gruntを私の現在のプロジェクトに使用することを選択し、GruntFileを作成しました。このGruntFileは、私が必要とするものの約90%を占めています。 manifest.jsonファイルにクロム拡張子を作成しているときに参照するJavaScriptファイルがいくつかあります。ビルドのプロセスでは、これらのファイルをすべて連結し、ファイルを1つに縮小してmanifest.jsonに含めます。ビルドプロセス中にmanifest.jsonファイル内のファイル参照を更新する必要がありますので、それは縮小バージョンを指していますか?ここでjsonファイル内のファイル参照を粗いタスクで更新する

は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", 
} 

私は1つのファイルに上記のすべてのjsファイルはinjection.jsと呼ばれ、変更することができ単調な作業をしたいと思い連結し、minifiesイサキのタスクを持っていますマニフェストファイルには、それは次のようになります。

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

私は今のところ行われ、ビルドプロセスにコピービルドバージョンの代わりに中に、マニフェストファイルの2つのバージョン、devに関する1およびビルドのための1つを持っているてきたもの。これは私がむしろやっていない2つのバージョンを維持する必要があることを意味します。グランツといっしょにこれをもっとエレガントにするにはどうしたらいいですか?

答えて

26

Gruntは、ファイルの読み書きのために、独自のAPIを提供します、私はfsのような他の依存性よりも良いが、と感じて

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

同様に 'grunt.file.readYAML'があり、HTTPを試してみてください/ /gruntjs.com/api/grunt.file info – tekkavi

+0

このコメントに気付きました。ありがとうございました。私は以来、browserifyを使用し始めて、それは最初の場所でこのスレッドを開始した理由は否定されています...しかし、私はまだ他の理由でfsを使ってファイルを読み書きしますが、これは本当に役に立ちます。 – Charles

11

私は同様のことを行います。マニフェストを読み込み、内容を更新してから再度シリアル化することができます。ような何か:あなたのgruntjsファイルでこのタスクを入れた後 編集/更新JSONファイルコマンドgrunt updatejson:key:valueで面倒を使用して:

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

私はここで他の回答に同意しません。

1)fsの代わりにgrunt.file.writeを使用する理由grunt.file.writeで、fs.writeFilySync(コードhere参照)のラッパーです。

2)なぜgruntがを本当に簡単にするのですかfs.writeFileSyncを使用する理由ものを非同期で処理しますか? には、ビルドプロセスで非同期のが必要であることは間違いありませんが、それが簡単な場合は、はなぜですか? (これは、実際には、writeFileSync実装よりも長いだけのカップルの文字です。)

私は次のことをお勧めしたい:

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

実際に 'require()'は同期FSですので、あなたのタスクは実際には完全に非同期ではありません。 –

+0

まあ、1つは、私はそれは言っていない。私は代わりに 'fs.writeFile'を' grunt.file.write'に提案しています(read:改善)。他の解決策もjsonファイルを 'require 'するので、これはまだ改善されています。あなたが_非同期的にタスク全体を非同期にすることを気にするなら、jsonマニフェストを 'fs.readFile'するか、タスク自体の外にrequireを移動させることができます(' fs'が必要な場所)。もちろん、マニフェストはタスクのロードとタスクの実行の間で変更されません)。 – tandrewnichols

+0

もう少し一般的なことは、 'fs'の代わりに' fs-extra'を使用し、欠落しているディレクトリパスを 'mkdir -p'する' outputFile'などのメソッドを使うことです。 – tandrewnichols

関連する問題