我是一名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一起更优雅地做到这一点?
答案 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
代替fs
? 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.
});