通过grunt任务更新json文件中的文件引用

时间:2013-06-11 19:35:52

标签: javascript node.js build gruntjs

我是一名JavaScript开发人员,从头开始创建构建过程相当新。我选择将Grunt用于我当前的项目,并创建了一个GruntFile,它可以完成我需要它做的大约90%的工作,除了这个问题之外它很有用。当我在manifest.json文件中开发chrome扩展时,我有几个JavaScript文件。对于我的构建过程,我将所有这些文件连接起来并将其缩小为一个文件以包含在manifest.json中。无论如何在构建过程中更新manifest.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",
}

我有一个繁琐的任务,将上面列出的所有js文件连接并缩小为一个名为injection.js的文件,并且想要一个可以修改清单文件的grunt任务,如下所示:

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

我现在所做的是有两个版本的清单文件,一个用于开发,一个用于构建,在构建过程中它会复制构建版本。这意味着我需要维护两个我不想做的版本。无论如何,与Grunt一起更优雅地做到这一点?

3 个答案:

答案 0 :(得分:29)

Grunt为阅读和编写文件提供了自己的api,我觉得比fs等其他依赖项更好: 将此任务放入gruntjs文件后,使用带有命令grunt updatejson:key:value的grunt编辑/更新json文件

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

    });

答案 1 :(得分:11)

我做了类似的事情 - 您可以加载清单,更新内容然后再将其序列化。类似的东西:

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

答案 2 :(得分:0)

我不同意这里的其他答案。

1)为什么使用grunt.file.write代替fsgrunt.file.write 只是 fs.writeFilySync的包装器(请参阅代码here)。

2)为什么当grunt使非常容易以异步方式执行操作时使用fs.writeFileSync?毫无疑问,您在构建过程中不需要异步,但如果它很容易做到,为什么不能<

/ em>的? (实际上,只有几个字符长于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.
});