Gulp合并来自不同文件夹的json文件,同时保持文件夹结构 [英] Gulp merge json files from different folders while keeping folder structure

查看:110
本文介绍了Gulp合并来自不同文件夹的json文件,同时保持文件夹结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



输入

  /lang/module1/file1.json 
/lang/module1/file2.json
/lang/module2/file1.json
/ lang /module2/subModule1/file1.json

/lang_additional/module1/file1.json
/lang_additional/module1/file2.json
/lang_additional/module2/file1.json
/lang_additional/module2/subModule1/file1.json

预期产量

  /dist/lang/module1/file1.json(均合并file1.json)
/dist/lang/module1/file2.json file2.json的合并)
/dist/lang/module2/file1.json(两个file1.json的合并)
/dist/lang/module2/subModule1/file1.json(两个file1.json的合并)

是否可以用gulp来实现这一点?可能有多个文件夹和子文件夹。我希望指定哪个父文件夹在合并冲突解决方案中具有优先权。 这适用于您的示例输入我相信每个文件夹中的任何数量的子文件夹。如果在另一个目录中有一个匹配的文件,它将被添加到一个流数组中,然后这个数组将被用于启动必要数量的gulp流,以保留文件夹结构,将其发送到'gulp-merge-json'和'dist'输出。



与gulp mergeJSON一起使用

  var gulp = require '吞'); 
var fs = require('fs');
var path = require('path');
var merge = require('gulp-merge-json');

const files = [];
const parentFolders = [];
let streams = [];
const baseNames = [];

//注意'gulp-merge-json'的作用方式是与合并
中的前一个文件'wins'具有相同键的最后一个文件//因此无论哪个目录是在文件夹数组中最后列出的将具有PRECEDENCE
//'gulp-merge-json'也将采用'编辑'功能选项

// [在你说的评论中你想要保留在'./dist'
//但是'lang_additional'的优先顺序]

//保留的'lang'文件夹结构顺便说一下,它可以处理两个以上的目录,或者它可以工作与
//不同级别的文件夹,如:
// const folders = ['lang','lang_additional / module1 / subModule2'];
//只将这些文件合并到最深
//级别的相同目录结构中。所以在上面的例子中,只能在subModule2和下面。

const folders = ['lang','lang_additional'];
$ b gulp.task('mergeJSON',function(){

getFiles(文件夹);
makeStreams();

/ / streams [1] = lang'\\module1\file2.json,lang_additional\module1\file2.json

//启动多个流,不是真正的流,直到吞噬。 src创建一个
streams.forEach(函数(流){

//从一个流文件中获取fileName,它们都以相同的文件结束
let fileName = path.basename(stream [stream.length - 1]);

//获取其中一个流的目录,流中的所有文件都具有相同的目录
let dirName = path.dirname(stream [stream.length - 1]);
//剥离第一个目录,保留所有子目录
dirName = dirName.substr(dirName.indexOf(path.sep));

return gulp.src(stream)
.pipe(merge({fileName:fileName}))

//因为问题需要dist / lang /子文件夹hiera rchy
.pipe(gulp.dest(path.join('./ dist','lang',dirName)));
});
});

// getFiles是递归的,如果fs.readdirSync检索到的文件是一个目录

函数getFiles(文件夹){

let possibleDirectory;

folders.forEach(function(folder,index){

//从每个目录读取文件列表
let tempFiles = fs.readdirSync('./ '文件夹);

tempFiles.forEach(function(fileOrDirectory){

possibleDirectory = path.join(folder,fileOrDirectory);
if(fs.lstatSync (possibleDirectory).isDirectory()){
getFiles([possibleDirectory]);
}
else {

//文件[]将包含所有在(文件或目录));

if $ b //如果该文件名元素尚不存在于baseName数组中
//仅包含真实文件的基本名称数组
aseNames.push(fileOrDirectory);
}
}
});
});

$ b $函数makeStreams(){

//对于每个文件,找到并保存其父目录而不使用文件夹[]root目录
files.forEach(function(file){

let thisParentFolders = path.dirname(file).substr(file.indexOf(path.sep));

if( parentFolders.indexOf(thisParentFolders)=== -1){

//如果该父文件夹不存在于baseName数组
parentFolders.push(thisParentFolders);
}
});

//现在通过所有独特的目录循环查找与每个parentFolder与baseName附加
parentFolders.forEach(函数(文件夹){

let foldersFile = folder.substr(folder.indexOf(path.sep));

baseNames.forEach(function(baseName){

streams.push(files.filter(function(file ){
return file.endsWith(path.join(foldersFile,baseName));
}));
});
});

//在这里:删除所有只有一个文件的streams(数组子元素),length == 1
//但是现在这个过滤器是必须的,因为一个未定义的条目。
streams = streams.filter(stream => stream.length> = 1); ((stream,index)=> console.log(streams [+ index +] =+ stream));

streams.forEach
}


I would like to merge multiple .json files from different folders while keeping the general folder structure.

Input

/lang/module1/file1.json
/lang/module1/file2.json
/lang/module2/file1.json
/lang/module2/subModule1/file1.json

/lang_additional/module1/file1.json
/lang_additional/module1/file2.json
/lang_additional/module2/file1.json
/lang_additional/module2/subModule1/file1.json

Expected Output

/dist/lang/module1/file1.json                (both file1.json's merged)
/dist/lang/module1/file2.json                (both file2.json's merged)
/dist/lang/module2/file1.json                (both file1.json's merged)
/dist/lang/module2/subModule1/file1.json     (both file1.json's merged)

Is it possible to achieve this with gulp? There may be multiple folders and subfolders. I wish to designate which parent folder has precedence in the merge conflict resolution.

解决方案

This works for your example input and I believe any number of subfolders in each folder. If there is a matching file in another directory it is added to a streams array that will then be used to start the necessary number of gulp streams to send to 'gulp-merge-json' and your 'dist' output with the folder structure retained.

Use with "gulp mergeJSON"

var gulp = require('gulp');
var fs = require('fs');
var path = require('path');
var merge = require('gulp-merge-json');

const files = [];
const parentFolders = [];
let   streams = [];
const baseNames = [];

//    note that the way 'gulp-merge-json' works is the last file having the same key as an earlier file 'wins' on the merge
//    so whichever directory is listed last in the folders array will have PRECEDENCE
//   'gulp-merge-json' will also take an 'edit' function option

// [  in the comments you said you wanted the 'lang' folder structure preserved in './dist'
//     but with 'lang_additional' precedence  ]

//  By the way, this works with more than two directories or it can work with
// folders of different levels such as:
//         const folders = ['lang', 'lang_additional/module1/subModule2'];
// only merging those files with the same directory structure starting at the deepest
// levels only. So in the above example, only within subModule2 and below.

const folders = ['lang', 'lang_additional'];

gulp.task('mergeJSON', function () {

  getFiles(folders);
  makeStreams();

    // streams[1] =   lang\module1\file2.json,   lang_additional\module1\file2.json

  // spin up multiple "streams", not really a stream yet until gulp.src creates one
  streams.forEach(function (stream) {

    //  get the fileName from one of the stream files, they all end with the same file
    let fileName = path.basename(stream[stream.length - 1]);

    //  get the directories of one of the streams, again all files within a stream have the same directories
    let dirName = path.dirname(stream[stream.length - 1]);
    // strip off the first directory, leaving all subdirectories
    dirName = dirName.substr(dirName.indexOf(path.sep));

    return gulp.src(stream)
      .pipe(merge({ fileName: fileName }))

      // since the question wanted a dist/lang/subfolders hierarchy
      .pipe(gulp.dest(path.join('./dist', 'lang', dirName)));
  });
});

// getFiles is recursive, if a "file" retrieved by fs.readdirSync is a directory

function getFiles(folders) {

  let possibleDirectory;

  folders.forEach(function (folder, index) {

    // read the file list from each directory
    let tempFiles = fs.readdirSync('./' + folder);

    tempFiles.forEach(function (fileOrDirectory) {

      possibleDirectory = path.join(folder, fileOrDirectory);
      if (fs.lstatSync(possibleDirectory).isDirectory())  {
        getFiles([possibleDirectory]);
      }
      else {

        // files[] will include all files found under the folders array
        files.push(path.join(folder, fileOrDirectory));

        if (baseNames.indexOf(fileOrDirectory) === -1) {

          // if that file name element doesn't already exist in baseName array
          // an array of just the basenames of true files
          baseNames.push(fileOrDirectory);
        }
      }
    });
  });
}

function makeStreams() {

  // for each file, find and save its parent directories without the folders[] "root" directories
  files.forEach(function (file) {

    let thisParentFolders = path.dirname(file).substr(file.indexOf(path.sep));

    if (parentFolders.indexOf(thisParentFolders) === -1) {

      // if that parentfolder  doesn't already exist in baseName array
      parentFolders.push(thisParentFolders);
    }
  });

  // now loop through all unique directories looking for those files with each parentFolder with baseName attached
  parentFolders.forEach(function (folder) {

    let foldersFile = folder.substr(folder.indexOf(path.sep));

    baseNames.forEach(function (baseName) {

      streams.push(files.filter(function (file) {
         return file.endsWith(path.join(foldersFile, baseName));
      }));
    });
  });

  //    Here: remove any "streams" (array sub-elements) that have only one file in them, length == 1
  //    But for now this filter is necessary due to a undefined entry in .
  streams = streams.filter( stream => stream.length >= 1);

  streams.forEach( (stream, index) => console.log("streams[" + index + "] = " + stream));
}

这篇关于Gulp合并来自不同文件夹的json文件,同时保持文件夹结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆