|
|
/* MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra */ "use strict";
const Stats = require("./Stats");
class Watching { constructor(compiler, watchOptions, handler) { this.startTime = null; this.invalid = false; this.handler = handler; this.callbacks = []; this.closed = false; this.suspended = false; if (typeof watchOptions === "number") { this.watchOptions = { aggregateTimeout: watchOptions }; } else if (watchOptions && typeof watchOptions === "object") { this.watchOptions = Object.assign({}, watchOptions); } else { this.watchOptions = {}; } this.watchOptions.aggregateTimeout = this.watchOptions.aggregateTimeout || 200; this.compiler = compiler; this.running = true; this.compiler.readRecords(err => { if (err) return this._done(err);
this._go(); }); }
_go() { this.startTime = Date.now(); this.running = true; this.invalid = false; this.compiler.hooks.watchRun.callAsync(this.compiler, err => { if (err) return this._done(err); const onCompiled = (err, compilation) => { if (err) return this._done(err); if (this.invalid) return this._done();
if (this.compiler.hooks.shouldEmit.call(compilation) === false) { return this._done(null, compilation); }
this.compiler.emitAssets(compilation, err => { if (err) return this._done(err); if (this.invalid) return this._done(); this.compiler.emitRecords(err => { if (err) return this._done(err);
if (compilation.hooks.needAdditionalPass.call()) { compilation.needAdditionalPass = true;
const stats = new Stats(compilation); stats.startTime = this.startTime; stats.endTime = Date.now(); this.compiler.hooks.done.callAsync(stats, err => { if (err) return this._done(err);
this.compiler.hooks.additionalPass.callAsync(err => { if (err) return this._done(err); this.compiler.compile(onCompiled); }); }); return; } return this._done(null, compilation); }); }); }; this.compiler.compile(onCompiled); }); }
_getStats(compilation) { const stats = new Stats(compilation); stats.startTime = this.startTime; stats.endTime = Date.now(); return stats; }
_done(err, compilation) { this.running = false; if (this.invalid) return this._go();
const stats = compilation ? this._getStats(compilation) : null; if (err) { this.compiler.hooks.failed.call(err); this.handler(err, stats); return; } this.compiler.hooks.done.callAsync(stats, () => { this.handler(null, stats); if (!this.closed) { this.watch( Array.from(compilation.fileDependencies), Array.from(compilation.contextDependencies), Array.from(compilation.missingDependencies) ); } for (const cb of this.callbacks) cb(); this.callbacks.length = 0; }); }
watch(files, dirs, missing) { this.pausedWatcher = null; this.watcher = this.compiler.watchFileSystem.watch( files, dirs, missing, this.startTime, this.watchOptions, ( err, filesModified, contextModified, missingModified, fileTimestamps, contextTimestamps, removedFiles ) => { this.pausedWatcher = this.watcher; this.watcher = null; if (err) { return this.handler(err); } this.compiler.fileTimestamps = fileTimestamps; this.compiler.contextTimestamps = contextTimestamps; this.compiler.removedFiles = removedFiles; if (!this.suspended) { this._invalidate(); } }, (fileName, changeTime) => { this.compiler.hooks.invalid.call(fileName, changeTime); } ); }
invalidate(callback) { if (callback) { this.callbacks.push(callback); } if (this.watcher) { this.compiler.fileTimestamps = this.watcher.getFileTimestamps(); this.compiler.contextTimestamps = this.watcher.getContextTimestamps(); } return this._invalidate(); }
_invalidate() { if (this.watcher) { this.pausedWatcher = this.watcher; this.watcher.pause(); this.watcher = null; }
if (this.running) { this.invalid = true; return false; } else { this._go(); } }
suspend() { this.suspended = true; this.invalid = false; }
resume() { if (this.suspended) { this.suspended = false; this._invalidate(); } }
close(callback) { const finalCallback = () => { this.compiler.hooks.watchClose.call(); this.compiler.running = false; this.compiler.watchMode = false; if (callback !== undefined) callback(); };
this.closed = true; if (this.watcher) { this.watcher.close(); this.watcher = null; } if (this.pausedWatcher) { this.pausedWatcher.close(); this.pausedWatcher = null; } if (this.running) { this.invalid = true; this._done = finalCallback; } else { finalCallback(); } } }
module.exports = Watching;
|