Return 使用 gulp-tap 将函数结果延迟到下一个 Gulp 管道
Return deferred function result to next Gulp pipe with gulp-tap
我正在创建一个简单的静态站点,在开发过程中,我正在使用 Handlebars.js 并进行一些 API 调用以填充 Handlebars 模板。但是对于生产,我想将所有模板预编译为静态 HTML.
我正在尝试使用 Gulp 使该过程自动化,所以我有一个看起来像这样的任务:
gulp.task('compileHtml', () => {
return gulp
.src('index.html')
.pipe(someThing())
.pipe(anotherThing())
.pipe(compileTemplates())
.pipe(someOtherThing())
.pipe(gulp.dest('build'));
});
在我的 compileTemplates
函数中,我使用 gulp-tap and jsdom 基本上 运行 包含相关脚本的文件,以进行 API 调用并填写 Handlebars 模板,然后删除那些脚本并将编译后的 HTML 发送回下一个管道。但是我无法推迟发回新的 DOM,直到 jsdom
有足够的时间来 运行 所有脚本。
这是我目前的情况:
const compileTemplates = file => {
return tap(file => {
const dom = new JSDOM(file.contents,
{
runScripts: 'dangerously',
resources: 'usable',
beforeParse(window) {
window.fetch = require('node-fetch');
},
},
);
const document = dom.window.document;
const script = document.querySelector('script[src$="handlebars.min.js"]');
// dom.serialize() still contains my uncompiled templates at this point
setTimeout(() => {
script.remove();
file.contents = Buffer.from(dom.serialize()); // this is what I want to return from this function
}, 2500);
});
};
我知道我可能需要使用承诺在准备就绪后发回 file.contents
,但我不擅长承诺或 Gulp。
我尝试返回一个在超时内解决的承诺,但我最终得到 TypeError: dest.on is not a function
,因为下一个管道最终期待 file
而不是承诺。
我如何重构以延迟将我操纵的 file
发回下一个管道或从该函数发回一个承诺,然后将该承诺解析为我的新 file
compileHtml
任务?
我正在使用 Gulp 4.
参考了,想通了超时后如何解决promise
const compileTemplates = file => {
return tap(file => {
const dom = new JSDOM(file.contents,
{
runScripts: 'dangerously',
resources: 'usable',
beforeParse(window) {
window.fetch = require('node-fetch');
},
},
);
const document = dom.window.document;
const script = document.querySelector('script[src$="handlebars.min.js"]');
new Promise(resolve => {
setTimeout(resolve, 2500);
}).then(() => {
script.remove();
file.contents = Buffer.from(dom.serialize());
});
});
};
然而,这并没有完全解决我的问题,因为在我的 gulp 任务中,我需要等待承诺得到解决,然后才能将新的 file
发送到下一个管道,但我不能在 gulp-tap
.
中找不到任何关于回调的好文档
所以我最终使用了 through2。
const compileHtml = file => {
return through2.obj(function(file, encoding, callback) {
const dom = new JSDOM(file.contents,
{
runScripts: 'dangerously',
resources: 'usable',
beforeParse(window) {
window.fetch = require('node-fetch');
},
},
);
const document = dom.window.document;
const script = document.querySelector('script[src$="handlebars.min.js"]');
new Promise(resolve => {
setTimeout(resolve, 2500);
}).then(() => {
script.remove();
file.contents = Buffer.from(dom.serialize());
this.push(file);
callback();
});
});
}
如果有人知道使用 gulp-tap
这个函数会是什么样子,请随时 post 回答!
我正在创建一个简单的静态站点,在开发过程中,我正在使用 Handlebars.js 并进行一些 API 调用以填充 Handlebars 模板。但是对于生产,我想将所有模板预编译为静态 HTML.
我正在尝试使用 Gulp 使该过程自动化,所以我有一个看起来像这样的任务:
gulp.task('compileHtml', () => {
return gulp
.src('index.html')
.pipe(someThing())
.pipe(anotherThing())
.pipe(compileTemplates())
.pipe(someOtherThing())
.pipe(gulp.dest('build'));
});
在我的 compileTemplates
函数中,我使用 gulp-tap and jsdom 基本上 运行 包含相关脚本的文件,以进行 API 调用并填写 Handlebars 模板,然后删除那些脚本并将编译后的 HTML 发送回下一个管道。但是我无法推迟发回新的 DOM,直到 jsdom
有足够的时间来 运行 所有脚本。
这是我目前的情况:
const compileTemplates = file => {
return tap(file => {
const dom = new JSDOM(file.contents,
{
runScripts: 'dangerously',
resources: 'usable',
beforeParse(window) {
window.fetch = require('node-fetch');
},
},
);
const document = dom.window.document;
const script = document.querySelector('script[src$="handlebars.min.js"]');
// dom.serialize() still contains my uncompiled templates at this point
setTimeout(() => {
script.remove();
file.contents = Buffer.from(dom.serialize()); // this is what I want to return from this function
}, 2500);
});
};
我知道我可能需要使用承诺在准备就绪后发回 file.contents
,但我不擅长承诺或 Gulp。
我尝试返回一个在超时内解决的承诺,但我最终得到 TypeError: dest.on is not a function
,因为下一个管道最终期待 file
而不是承诺。
我如何重构以延迟将我操纵的 file
发回下一个管道或从该函数发回一个承诺,然后将该承诺解析为我的新 file
compileHtml
任务?
我正在使用 Gulp 4.
参考了
const compileTemplates = file => {
return tap(file => {
const dom = new JSDOM(file.contents,
{
runScripts: 'dangerously',
resources: 'usable',
beforeParse(window) {
window.fetch = require('node-fetch');
},
},
);
const document = dom.window.document;
const script = document.querySelector('script[src$="handlebars.min.js"]');
new Promise(resolve => {
setTimeout(resolve, 2500);
}).then(() => {
script.remove();
file.contents = Buffer.from(dom.serialize());
});
});
};
然而,这并没有完全解决我的问题,因为在我的 gulp 任务中,我需要等待承诺得到解决,然后才能将新的 file
发送到下一个管道,但我不能在 gulp-tap
.
所以我最终使用了 through2。
const compileHtml = file => {
return through2.obj(function(file, encoding, callback) {
const dom = new JSDOM(file.contents,
{
runScripts: 'dangerously',
resources: 'usable',
beforeParse(window) {
window.fetch = require('node-fetch');
},
},
);
const document = dom.window.document;
const script = document.querySelector('script[src$="handlebars.min.js"]');
new Promise(resolve => {
setTimeout(resolve, 2500);
}).then(() => {
script.remove();
file.contents = Buffer.from(dom.serialize());
this.push(file);
callback();
});
});
}
如果有人知道使用 gulp-tap
这个函数会是什么样子,请随时 post 回答!