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

Updating file references in a json file via a grunt task

本文关键字:文件 引用 json grunt 任务 更新 通过      更新时间:2023-09-26

我是一名JavaScript开发人员,对从头开始创建构建过程相当陌生。我选择在我目前的项目中使用Grunt,并创建了一个GruntFile,它可以完成我需要它做的90%的事情,而且它工作得很好,除了这个问题。我有几个JavaScript文件,我引用,而我正在开发一个chrome扩展的manifest.json文件。对于我的构建过程,我将所有这些文件连接起来,并将其缩小为一个文件,以便包含在manifest.json中。在构建过程中是否有更新manifest.json文件中的文件引用,因此它指向缩小的版本?

下面是src manifest文件的一个片段:

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

我有一个grunt任务,它将上面列出的所有js文件连接并最小化到一个名为injection.js的文件中,并且想要一个grunt任务,可以修改清单文件,使其看起来像这样:

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

我现在所做的是有2个版本的清单文件,一个用于开发,一个用于构建,在构建过程中,它复制构建版本。这意味着我需要维护两个版本,我宁愿不这样做。有没有什么方法可以让Grunt做得更优雅?

Grunt提供了自己的api来读取和写入文件,我觉得这比其他依赖如fs要好:把这个任务放在你的gruntjs文件后,使用grunt命令grunt updatejson:key:value编辑/更新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
    });

我做了类似的事情-您可以加载您的清单,更新内容,然后再次序列化它。比如:

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

我不同意其他的答案。

1)为什么用grunt.file.write代替fs ?grunt.file.write只是 fs.writeFilySync的包装(见这里的代码)。

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