gulp - 合并2个文件夹,为具有相同名称的文件选择操作

时间:2016-08-11 16:19:28

标签: gulp

我需要在另一个文件夹中复制2个文件夹的内容。 如果存在具有相同名称的文件,并且根据文件扩展名,则执行以下函数: - concat:JS,LESS ...... - 合并:json - 覆盖:图像,HTML ......

要复制2个文件夹不是问题,它是第二部分:(

var route = 'bower_components/any-folder';
gulp.task('test', function() {
    return gulp.src([route + '**/*', 'source/**/*', route + '!bower_components{,/**}', route + '!node_modules{,/**}'])
        .pipe( $.replace( '@@_APP_@@', 'myApp' ) )
        .pipe(gulp.dest('./temp'));
});

有人可以提供任何帮助。

编辑:我的基础设施图

|-gulpfile.js
|-bower_components
|   |-module
|   |   |-bower.json
|   |   |-package.json
|   |   |-index.less
|   |   |-hello.png
|-source
|   |-bower.json
|   |-package.json
|   |-index.less
|   |-hello.png

这就是我想要的:

|-public
|   |-bower.json (merge between bower_components/module & source)
|   |-package.json (merge between bower_components/module & source)
|   |-index.less (concat between bower_components/module & source)
|   |-hello.png (provide from source, overwrite the copy from bower_components/module)

2 个答案:

答案 0 :(得分:1)

您想要覆盖文件的情况最简单,因为gulp.dest默认覆盖,并且gulp.src按顺序处理指定的文件。您希望源文件优先于bower_components中的文件使用。所以这样的事情应该有用

gulp.task('overwrite', () => {
  gulp.src('./bower_components/**/*.png', './source/**/*.png')
  .pipe(gulp.dest('./temp'));
});

因此,如果该文件存在于两个位置,则来自源文件的文件将覆盖./temp中bower_components中的文件。

尝试开始

答案 1 :(得分:0)

对于任何寻找任意解决方案的人,我想出了以下转换流(使用through2实现),以便根据任意键对文件进行分组:

function groupFiles(
    keyFunc = file => file.relative,
    newFunc = newConcatFile,
    mergeFunc = appendConcatFile,
    flushFunc = flushConcatFile) {
  const groups = {}
  return through2.obj(
    function (file, _encoding, callback) {
      const key = keyFunc(file)
      let chunk
      let state = groups[key]
      if (state === undefined) {
        ({ chunk, state } = newFunc(key, file))
      } else {
        ({ chunk, state } = mergeFunc(key, file, state))
      }
      groups[key] = state
      callback(null, chunk)
    },
    function (callback) {
      const keys = Object.keys(groups)
      keys.forEach(key => {
        const state = groups[key]
        flushFunc(key, state, this)
      })
      callback()
    })
}

默认情况下,它会根据相对路径连接文件:

function newConcatFile(key, file) {
  const chunk = file.clone({ contents: false })
  const state = new ConcatSource({}, file.contents)
  chunk.contents = state
  return { chunk, state }
}

function appendConcatFile(key, file, state) {
  state.addSource(file.contents)
  return { chunk: null, state }
}

function flushConcatFile(key, state) {
  state.end()
}

ConcatSource是一个Readable流,可以附加缓冲区,字符串或流:

class ConcatSource extends Readable {
  constructor(options, sources) {
    super(options)
    this._sources = Array.isArray(sources) ? sources : sources != null ? [sources] : []
    this._currentSource = null
    this._readPending = false
    this._noMoreSources = false
  }
  _read(size) {
    for (;;) {
      let source = this._currentSource
      if (source == null) {
        if (this._sources.length > 0) {
          source = this._currentSource = this._sources.shift()
        } else if (this._noMoreSources) {
          this.push(null)
          break
        } else {
          this._readPending = size || true
          break
        }
      }
      let data
      if (Buffer.isBuffer(source) || typeof source === 'string') {
        data = source
        this._currentSource = null
      } else {
        data = source.read(size)
        if (data == null) {
          this._currentSource = null
          continue
        }
      }
      if (!this.push(data)) {
        break
      }
    }
  }
  addSource(source) {
    if (this._noMoreSources) {
      this.emit('error', new Error('end() has been called'))
    } else if (source) {
      this._sources.push(source)
      if (this._readPending) {
        this._read(this._readPending !== true ? this._readPending : undefined)
      }
    }
  }
  end() {
    this._noMoreSources = true
    if (this._readPending) {
      this.push(null)
      this._readPending = false
    }
  }
}