【问题标题】:Replacing strings with values from an array with Gulp使用 Gulp 将字符串替换为数组中的值
【发布时间】:2020-07-04 03:54:44
【问题描述】:

我正在尝试指示gulp-replace 将我的files 中给定字符串flexes[i][0] 的所有实例替换为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 替换为:

  • New A 如果传递的模式参数是 1 或
  • 新的 B 如果传递的模式参数是 2

并保存到输出文件夹。

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)

我应该如何解决它?

【问题讨论】:

  • forEach 返回未定义。管道正在等待流。

标签: javascript gulp gulp-replace


【解决方案1】:

.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))
}

如果您有很多要替换的内容并发现性能问题,您可以考虑使用| 创建一个串联的正则表达式。你可能不需要它。

【讨论】:

  • 谢谢!如何将mode 参数传递到您的解决方案中? 如果我在顶部全局声明它,它会起作用,所有其他参数为:const mode = 1 但是当我尝试直接传递它时它会生成 AssertionError :const prev = gulp.series(repla(1), otherFunction); exports.prev = prev
  • 这很奇怪。模式不应该影响这一点。你使用的是什么版本的 gulp?吞咽 4?你能为脚本提供更多上下文吗?
  • gulp.series( (cb)=>{repla(1);cb()}, otherFunction )? gulp.series 应该期待一个字符串(任务名称)或函数(回调函数),而不是 gulp 链本身
  • 是的,我使用 Gulp 4.0.2。我将该函数隔离到它自己的、单独的 gulpfile.js 中,以消除与其他元素的干扰,直到我使 repla 工作。设置就像上面发布的我的设置。我将 My function 替换为您的,并尝试使其直接与 exports.prod = repla(2)const prev = gulp.series(repla(2)); exports.prev = prev 一起使用。我可以使它工作的唯一方法是通过在 我的设置 中设置模式值或手动将其从 element[mode] 更改为 element[2]
  • 你想传递 (cb)=>{repla(1);cb()} 而不是 repla(1)。 series 和 parallel 采用函数或字符串,但您传递的是 gulp 链。这在将 gulp 链引用传递给系列之前是否有效? repla(1) 返回 gulp.src.pipe... 的返回输出,但 series 需要一个函数或字符串
【解决方案2】:

这是一种不需要任何类型的 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 以查找同时使用 forEachgulp 的问题)。

修改后的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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-12
    • 2013-11-08
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2014-02-01
    • 2012-11-25
    相关资源
    最近更新 更多