我正在创建一个简单的静态网站,在开发中,我在其中使用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和jsdom基本上使用相关脚本来运行文件以进行API调用并填写Handlebars模板,然后删除这些模板脚本并将已编译的HTML发送回下一个管道。但是在jsdom
有足够的时间运行所有脚本之前,我很难将发回新的DOM发送回来。
这是我到目前为止所拥有的:
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
发送回下一个管道,还是从该函数中发送一个承诺,然后将该承诺解析到我的{{1 }}任务?
我正在使用Gulp 4。
答案 0 :(得分:0)
咨询Using setTimeout on Promise Chain之后,我想出了如何在超时后解决承诺。
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());
});
});
};
但是,这并不能完全解决我的问题,因为在将新的file
发送到gulp任务中的下一个管道之前,我需要等待该承诺解决,但是我找不到任何好的文档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
时该功能的外观,请随时发布答案!