Updating file references in a json file via a grunt task

I'm a JavaScript developer and fairly new to creating a build process from scratch. I chose to use Grunt for my current project and have created a GruntFile that does about 90% of what I need it to do and it works great, except for this one issue. I have several JavaScript files that I reference while I'm developing a chrome extension in the manifest.json file. For my build process I am concatenating all of these files and minifying it into one file to be included in manifest.json. Is there anyway to update the file references in the manifest.json file during the build process so it points to the minified version?

Here is a snippet of the src manifest file:

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

I have a grunt task that concatenates and minifies all the js files listed above into one file called injection.js and would like a grunt task that can modify the manifest file so it looks like this:

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

What I've done for now is have 2 versions of the manifest file, one for dev and one for build, during the build process it copies the build version instead. This means I need to maintain 2 versions which I'd rather not do. Is there anyway to do this more elegantly with Grunt?

Grunt gives its own api for reading and writing files, i feel that better than other dependencies like fs: Edit/update json file using grunt with command grunt updatejson:key:value after putting this task in your gruntjs file

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

    });

I do something similar - you can load your manifest, update the contents then serialize it out again. Something like:

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));
});

I disagree with the other answers here.

1) Why use grunt.file.write instead of fs? grunt.file.write is just a wrapper for fs.writeFilySync (see code here).

2) Why use fs.writeFileSync when grunt makes it really easy to do stuff asynchronously? There's no doubt that you don't need async in a build process, but if it's easy to do, why wouldn't you? (It is, in fact, only a couple characters longer than the writeFileSync implementation.)

I'd suggest the following:

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.
});