使用 gulp-awspublish 将单个文件写入多个 s3 存储桶

Writing a single file to multiple s3 buckets with gulp-awspublish

我有一个简单的单页应用程序,它使用 gulp-awspublish. We use inquirer.js (via gulp-prompt) 部署到 S3 存储桶,询问开发人员要部署到哪个存储桶。

有时应用程序可能会部署到多个 S3 存储桶。目前,我们只允许 select 编辑一个桶,因此开发人员必须依次 gulp deploy 每个桶。这很乏味且容易出错。

我希望能够 select 多个存储桶并向每个存储桶部署相同的内容。使用查询器 select 多个存储桶很简单。js/gulp-prompt,但从单个流生成任意多个 S3 目的地并不简单。

我们的 deploy 任务是基于 generator-webapp 的 S3 recipe. The recipe suggests gulp-rename 重写写入特定存储桶的路径。目前我们的任务是这样的:

gulp.task('deploy', ['build'], () => {
  // get AWS creds
  if (typeof(config.awsCreds) !== 'object') {
    return console.error('No config.awsCreds settings found. See README');
  }

  var dirname;
  const publisher = $.awspublish.create({
    key: config.awsCreds.key,
    secret: config.awsCreds.secret,
    bucket: config.awsCreds.bucket
  });

  return gulp.src('dist/**/*.*')
    .pipe($.prompt.prompt({
      type: 'list',
      name: 'dirname',
      message: 'Using the ‘' + config.awsCreds.bucket + '’ bucket. Which hostname would you like to deploy to?',
      choices: config.awsCreds.dirnames,
      default: config.awsCreds.dirnames.indexOf(config.awsCreds.dirname)
    }, function (res) {
      dirname = res.dirname;
    }))
    .pipe($.rename(function(path) {
        path.dirname = dirname + '/dist/' + path.dirname;
    }))
    .pipe(publisher.publish())
    .pipe(publisher.cache())
    .pipe($.awspublish.reporter());
});

这很明显,但 config.awsCreds 可能类似于:

awsCreds: {
  dirname: 'default-bucket',
  dirnames: ['default-bucket', 'other-bucket', 'another-bucket']
}

Gulp-rename 重写目标路径以使用正确的存储桶。

对于 gulp-prompt 选项,我们可以通过使用 "checkbox" 而不是 "list" 来 select 多个存储桶,但我不确定如何将其传递给多个存储桶桶。

简而言之,如果 $.prompt returns 字符串数组而不是字符串,我如何将源写入多个目的地(桶)而不是单个桶?

请记住,gulp.dest() 未被使用——仅 gulp.awspublish()——而且我们不知道有多少桶可能被 selected。

从未使用过 S3,但如果我正确理解你的问题,文件 js/foo.js 应该重命名为 default-bucket/dist/js/foo.jsother-bucket/dist/js/foo.js 当复选框 default-bucketother-bucket被选中了?

那么这应该可以解决问题:

// additionally required modules
var path = require('path');
var through = require('through2').obj;

gulp.task('deploy', ['build'], () => {
  if (typeof(config.awsCreds) !== 'object') {
    return console.error('No config.awsCreds settings found. See README');
  }

  var dirnames = []; // array for selected buckets
  const publisher = $.awspublish.create({
    key: config.awsCreds.key,
    secret: config.awsCreds.secret,
    bucket: config.awsCreds.bucket
  });

  return gulp.src('dist/**/*.*')
    .pipe($.prompt.prompt({
      type: 'checkbox', // use checkbox instead of list
      name: 'dirnames', // use different result name
      message: 'Using the ‘' + config.awsCreds.bucket + 
               '’ bucket. Which hostname would you like to deploy to?',
      choices: config.awsCreds.dirnames,
      default: config.awsCreds.dirnames.indexOf(config.awsCreds.dirname)
    }, function (res) {
      dirnames = res.dirnames; // store array of selected buckets
    }))
    // use through2 instead of gulp-rename
    .pipe(through(function(file, enc, done) {
      dirnames.forEach((dirname) => {
        var f = file.clone();
        f.path = path.join(f.base, dirname, 'dist',
                           path.relative(f.base, f.path));
        this.push(f);
      });
      done();
    }))
    .pipe(publisher.cache())
    .pipe($.awspublish.reporter());
});

请注意我根据您发布的代码所做更改的评论。

它的作用是使用 through2 克隆通过流的每个文件。每个文件被克隆的次数与选中的存储桶复选框一样多,并且每个克隆都被重命名以结束在不同的存储桶中。