[英]“Write after end”: how to imitate gulp-watch with watchify?
以下Gulp任務幾乎完成了我想要的。
const gulp = require('gulp');
const browserify = require('browserify');
const vinylStream = require('vinyl-source-stream');
const vinylBuffer = require('vinyl-buffer');
const watchify = require('watchify');
const glob = require('glob');
const jasmineBrowser = require('gulp-jasmine-browser');
gulp.task('test', function() {
let testBundler = browserify({
entries: glob.sync('src/**/*-test.js'),
cache: {},
packageCache: {},
}).plugin(watchify);
function updateSpecs() {
return testBundler.bundle()
.pipe(vinylStream(jsBundleName))
.pipe(vinylBuffer())
.pipe(jasmineBrowser.specRunner({console: true}))
.pipe(jasmineBrowser.headless({driver: 'phantomjs'}));
}
testBundler.on('update', updateSpecs);
updateSpecs();
});
它使用Browserify捆綁了我的所有Jasmine規格,並通過gulp -jasmine-browser對其進行了測試。 它還會監視它們依賴的所有規格和所有模塊,並在這些模塊中的任何一個發生更改時重新運行測試。
我真正想解決的唯一丑陋之處是,每次運行updateSpecs
時, updateSpecs
創建一個新的PhantomJS實例和一個新的Jasmine服務器。 我希望通過以下代碼避免這種情況:
gulp.task('test', function() {
let testBundler = browserify({
entries: glob.sync('src/**/*-test.js'),
cache: {},
packageCache: {},
}).plugin(watchify);
// persist the Jasmine server and PhantomJS browser
let testServer = jasmineBrowser.headless({driver: 'phantomjs'});
function updateSpecs() {
return testBundler.bundle()
.pipe(vinylStream(jsBundleName))
.pipe(vinylBuffer())
.pipe(jasmineBrowser.specRunner({console: true}))
.pipe(testServer);
}
testBundler.on('update', updateSpecs);
updateSpecs();
});
las,這行不通。 在開始任務之后,所有測試都可以正常運行,但是下次調用updateSpecs
,我收到一個write after end
錯誤,並且該任務以狀態1退出。此錯誤源自readable-stream
Node模塊。
據我了解,在第一次運行updateSpecs
期間的end
事件使testServer
處於不接受任何新輸入的狀態。 不幸的是, Node.js流文檔尚不清楚如何解決此問題。
我曾嘗試在不同的位置斷開管道鏈,但得到的結果相同,這似乎表明這是流的普遍行為。 我還嘗試通過插入不重新發送該事件的流來阻止end
事件的傳播,但這完全無法運行測試。 最后,我嘗試從任務中return
testServer
流。 這停止了錯誤,但是盡管每次更改源時都會調用updateSpecs
函數,但是僅在任務首次啟動時運行測試。 這次, testServer
似乎只是忽略了新輸入。
gulp-jasmine-browser文檔建議使用以下代碼:
var watch = require('gulp-watch');
gulp.task('test', function() {
var filesForTest = ['src/**/*.js', 'spec/**/*-test.js'];
return gulp.src(filesForTest)
.pipe(watch(filesForTest))
.pipe(jasmineBrowser.specRunner())
.pipe(jasmineBrowser.server());
});
並繼續建議您也可以使用Browserify進行此操作,但這沒有說明。 顯然,gulp-watch會執行某些操作,從而導致后續管道在以后接受更新的輸入。 如何使用watchify模仿這種行為?
事實證明,這是Node.js中的硬規則,您無法在end
事件之后編寫該規則。 此外, jasmineBrowser.specRunner()
.server()
和.headless()
必須接收end
,以實際測試的任何信號。 此限制是從官方的Jasmine測試跑步者繼承而來的。
由於相同的原因,自述文件中帶有gulp-watch
的示例也不起作用。 為了使其工作,必須執行與問題中我的watchify
代碼的工作版本相似的操作:
gulp.task('test', function() {
var filesForTest = ['src/**/*.js', 'spec/**/*-test.js'];
function runTests() {
return gulp.src(filesForTest)
.pipe(jasmineBrowser.specRunner())
.pipe(jasmineBrowser.server());
}
watch(filesForTest).on('add change unlink', runTests);
});
(我沒有對其進行測試,但是與此非常接近的東西應該可以工作。)
因此,無論您使用.specRunner()
監視機制,都始終需要在每個周期中再次調用.specRunner()
和.server()
。 好消息是,顯然,如果您明確傳遞端口號,Jasmine服務器將被重用:
.pipe(jasmineBrowser.server({port: 8080}));
這也適用於.headless()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.