An appropriate way to concatenate JSON files with Grunt

I am looking for a better way to combine json files supporting a specific structure using Grunt.

Files are located in folders in the following structure:

  The app
 ├── locales
 │ ├── en
 │ │ └── translation.json
 │ ├── es
 │ │ └── translation.json
 │ └── fr
 │ └── translation.json
 └── widgets
     ├── Posts
     │ └── locales
     │ ├── en
     │ │ └── translation.json
     │ ├── es
     │ │ └── translation.json
     │ └── fr
     │ └── translation.json
     ├── Comments
     │ └── locales
     │ ├── en
     │ │ └── translation.json
     │ ├── es
     │ │ └── translation.json
     │ └── fr
     │ └── translation.json
     └── Links
         ├── locales
         │ ├── en
         │ │ └── translation.json
         │ ├── es
         │ │ └── translation.json
         │ └── fr
         │ └── translation.json

And the desired result with the merged files would be:

  The app
 │
 ├── lang
 │ ├── en
 │ │ └── translation.json
 │ ├── es
 │ │ └── translation.json
 │ └── fr
 │ └── translation.json
 ├── locales
 └── widgets

So far I have come up with one solution using grunt-contrib-concat, but I think there should be a better way to do this.

concat: { translateEN: { src: [ 'www/js/app/locales/en/*.json', 'www/js/app/widgets/posts/locales/en/*.json', 'www/js/app/widgets/comments/locales/en/*.json', 'www/js/app/widgets/links/locales/en/*.json' ], dest: 'www/js/app/lang/en/translation.json', options: { banner: '{', footer: "}", separator: ',' } }, translateES: { src: [ 'www/js/app/locales/es/*.json', 'www/js/app/widgets/posts/locales/es/*.json', 'www/js/app/widgets/comments/locales/es/*.json', 'www/js/app/widgets/links/locales/es/*.json' ], dest: 'www/js/app/lang/es/translation.json', options: { banner: '{', footer: "}", separator: ',' } }, translateFR: { src: [ 'www/js/app/locales/fr/*.json', 'www/js/app/widgets/posts/locales/fr/*.json', 'www/js/app/widgets/comments/locales/fr/*.json', 'www/js/app/widgets/links/locales/fr/*.json' ], dest: 'www/js/app/lang/fr/translation.json', options: { banner: '{', footer: "}", separator: ',' } } } 
+4
source share
1 answer

I ended up writing my own task:

  grunt.task.registerMultiTask('buildLocales', 'Build Locale files.', function() { var that = this, len = this.filesSrc.length, outputDir, outputFile, originalFile, destFile, merged; var jsonConcat = function(object1, object2) { var key, a1, a2; for (key in object2) { if (object2.hasOwnProperty(key)) { a2 = object2[key]; a1 = object1[key]; if (a1) { a1.push.apply(a1, a2); } else { object1[key] = a2; } } } return object1; }; var iterateTroughFiles = function(abspath, rootdir, subdir, filename){ if (abspath.indexOf('/.svn') === -1){ outputDir = that.data.dest + '/' + subdir; outputFile = outputDir + '/' + filename; // If output dir doesnt exists, then create it if (!grunt.file.exists(outputDir)) { grunt.file.mkdir(outputDir); } originalFile = grunt.file.readJSON(abspath); // if dest file doenst exist, then just copy it. if (!grunt.file.exists(outputFile)) { grunt.file.write(outputFile, JSON.stringify(originalFile)); } else { // read source file, read dest file. merge them. write it in dest file destFile = grunt.file.readJSON(outputFile); merged = jsonConcat(destFile, originalFile); grunt.file.write(outputFile, JSON.stringify(merged)); } } }; for (var x = 0; x < len; x++) { grunt.file.recurse(this.filesSrc[x], iterateTroughFiles); } }); 

And the implementation looks something like this:

 buildLocales: { locales:{ src: [ 'www/js/app/**/locales' ], dest: PATH_BUILD_LANGUAGES } }, 
+2
source

All Articles