>我正在尝试指示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"
]
]
我的函数
对于所有输入文件,函数应将所有旧文件替换为:
- 如果传递的模式参数为 1 或 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)
我应该如何解决它?
.pipe
需要一个流。.forEach
返回 undefined,它作为参数传递给管道,这就是您收到该错误的原因.
管道的工作方式是将流传递给.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))
}
如果您有很多东西要替换并看到性能问题,您可以考虑使用|
创建一个级联正则表达式。 您可能不需要它。
这是一种不需要任何类型的 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 prev
或gulp prod
这种方法确实要求您能够创建一个与要替换的所有字符串匹配的正则表达式,如/Old 1|Old 2/g
. 这对您来说可能是不可能的,但它可能只是/string1|string2|string3/g
或更复杂。 显然,如果你有很多这样的循环,for..in
循环可能是必要的(但我不会使用forEach
循环 - 搜索SO寻找一起使用forEach
和gulp
的问题(。
修改后的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=0
或gulp replace --mode=1