0

我正在尝试指示gulp-replaceflexes[i][0]将my中给定字符串的所有实例替换files为两个值之一flexes[i][1]flexes[i][2].

我的设置

const gulp = require('gulp'),
replace = require('gulp-replace'),

files = {
    input: 'input/*.html',
    output: 'output/'
},

flexes = [
    [
        "Old 1",
        "New 1A",
        "New 1B"
    ],[
        "Old 2",
        "New 2A",
        "New 2B"
    ]
]

我的功能

对于所有输入文件,函数应将所有Old替换为:

  • 如果传递的模式参数为 1,则为新 A或
  • 如果传递的模式参数为 2,则为新 B

并保存到输出文件夹。

function repla(mode) {
    return gulp
        .src(files.test_htm)
        .pipe(
            flexes.forEach(
                element => replace(
                    element[0], 
                    element[mode]
                )
            )
        )
        .pipe(gulp.dest(files.test))
}

exports.prev = repla(1)
exports.prod = repla(2)

exports.default = repla(1)  

错误

我的解决方案产生错误

TypeError: Cannot read property 'on' of undefined
    at DestroyableTransform.Readable.pipe (/node_modules/readable-stream/lib/_stream_readable.js:564:8)
    at repla (/gulpfile.js:39:10)
    at default (/node_modules/undertaker/lib/set-task.js:13:15)
    at bound (domain.js:426:14)
    at runBound (domain.js:439:12)
    at asyncRunner (/node_modules/async-done/index.js:55:18)
    at processTicksAndRejections (internal/process/task_queues.js:79:11)

我应该如何解决它?

4

2 回答 2

0

这是一种不需要任何类型的 for 循环的方法。它使用gulp-replace' 获取函数的能力:

  // this form of your replaces is much easier to work with
let flexes = {
  "Old 1": ["New 1A", "New 1B"],
  "Old 2": ["New 2A", "New 2B"]
};
 
function replaceStrings(mode) {

  return gulp.src(files.input)
    
    .pipe(replace(/Old 1|Old 2/g, function (match) {

      // console.log(flexes[match][mode]);    // e.g., "New 1A" 
      return flexes[match][mode];
    }))
    .pipe(gulp.dest('build/'));
};

exports.prev = gulp.series(() => replaceStrings(0));
exports.prod = gulp.series(() => replaceStrings(1));

exports.prev = gulp.series(() => replaceStrings(0));是将参数传递给任务函数的简单方法。

致电:gulp prevgulp prod

这种方法确实要求您能够制作一个匹配所有要替换的字符串的正则表达式,如/Old 1|Old 2/g. 这对您来说可能是不可能的,但它可以简单地/string1|string2|string3/g或更复杂。显然,如果你有很多这样的for..in循环可能是必要的(但我不会使用forEach循环 - 搜索 SO 以查找使用forEachandgulp一起的问题)。

修改后的flexes数据结构,允许一个非常简单的替换功能:

return flexes[match][mode];



我个人认为更好的方法是在命令行中使用 args。

const yargs = require('yargs');
const argv = yargs.argv;

function replaceStrings() {

  return gulp.src(files.input)
    
    .pipe(replace(/Old 1|Old 2/g, function (match) {

     //  console.log(argv.mode);  // 0 or 1
      return flexes[match][argv.mode];
    }))
    .pipe(gulp.dest('build/'));
};

exports.replace = gulp.series(replaceStrings);

致电:gulp replace --mode=0gulp replace --mode=1

于 2020-07-12T22:38:53.630 回答
0

.pipe需要一个流。 .forEach返回未定义,它作为参数传递给管道,这就是您收到该错误的原因。
管道的工作方式是您将流传递给.pipe它以链接输入和输出。在这种情况下,您可以做的是保留对 gulp 链的引用,并在其上使用循环链接管道:

function repla(mode) {
    var g = gulp
        .src(files.test_htm)

        flexes.forEach(
          element => g = g.pipe(replace(
            element[0], 
            element[mode]
          ))
        )

    return g.pipe(gulp.dest(files.test))
}

如果您有很多要替换的内容并看到性能问题,您可以考虑使用|. 你可能不需要它。

于 2020-07-04T05:27:33.950 回答