Projekt

Obecné

Profil

Stáhnout (4.79 KB) Statistiky
| Větev: | Revize:
1
/*
2
	MIT License http://www.opensource.org/licenses/mit-license.php
3
	Author Tobias Koppers @sokra
4
*/
5
"use strict";
6

    
7
const Stats = require("./Stats");
8

    
9
class Watching {
10
	constructor(compiler, watchOptions, handler) {
11
		this.startTime = null;
12
		this.invalid = false;
13
		this.handler = handler;
14
		this.callbacks = [];
15
		this.closed = false;
16
		this.suspended = false;
17
		if (typeof watchOptions === "number") {
18
			this.watchOptions = {
19
				aggregateTimeout: watchOptions
20
			};
21
		} else if (watchOptions && typeof watchOptions === "object") {
22
			this.watchOptions = Object.assign({}, watchOptions);
23
		} else {
24
			this.watchOptions = {};
25
		}
26
		this.watchOptions.aggregateTimeout =
27
			this.watchOptions.aggregateTimeout || 200;
28
		this.compiler = compiler;
29
		this.running = true;
30
		this.compiler.readRecords(err => {
31
			if (err) return this._done(err);
32

    
33
			this._go();
34
		});
35
	}
36

    
37
	_go() {
38
		this.startTime = Date.now();
39
		this.running = true;
40
		this.invalid = false;
41
		this.compiler.hooks.watchRun.callAsync(this.compiler, err => {
42
			if (err) return this._done(err);
43
			const onCompiled = (err, compilation) => {
44
				if (err) return this._done(err);
45
				if (this.invalid) return this._done();
46

    
47
				if (this.compiler.hooks.shouldEmit.call(compilation) === false) {
48
					return this._done(null, compilation);
49
				}
50

    
51
				this.compiler.emitAssets(compilation, err => {
52
					if (err) return this._done(err);
53
					if (this.invalid) return this._done();
54
					this.compiler.emitRecords(err => {
55
						if (err) return this._done(err);
56

    
57
						if (compilation.hooks.needAdditionalPass.call()) {
58
							compilation.needAdditionalPass = true;
59

    
60
							const stats = new Stats(compilation);
61
							stats.startTime = this.startTime;
62
							stats.endTime = Date.now();
63
							this.compiler.hooks.done.callAsync(stats, err => {
64
								if (err) return this._done(err);
65

    
66
								this.compiler.hooks.additionalPass.callAsync(err => {
67
									if (err) return this._done(err);
68
									this.compiler.compile(onCompiled);
69
								});
70
							});
71
							return;
72
						}
73
						return this._done(null, compilation);
74
					});
75
				});
76
			};
77
			this.compiler.compile(onCompiled);
78
		});
79
	}
80

    
81
	_getStats(compilation) {
82
		const stats = new Stats(compilation);
83
		stats.startTime = this.startTime;
84
		stats.endTime = Date.now();
85
		return stats;
86
	}
87

    
88
	_done(err, compilation) {
89
		this.running = false;
90
		if (this.invalid) return this._go();
91

    
92
		const stats = compilation ? this._getStats(compilation) : null;
93
		if (err) {
94
			this.compiler.hooks.failed.call(err);
95
			this.handler(err, stats);
96
			return;
97
		}
98
		this.compiler.hooks.done.callAsync(stats, () => {
99
			this.handler(null, stats);
100
			if (!this.closed) {
101
				this.watch(
102
					Array.from(compilation.fileDependencies),
103
					Array.from(compilation.contextDependencies),
104
					Array.from(compilation.missingDependencies)
105
				);
106
			}
107
			for (const cb of this.callbacks) cb();
108
			this.callbacks.length = 0;
109
		});
110
	}
111

    
112
	watch(files, dirs, missing) {
113
		this.pausedWatcher = null;
114
		this.watcher = this.compiler.watchFileSystem.watch(
115
			files,
116
			dirs,
117
			missing,
118
			this.startTime,
119
			this.watchOptions,
120
			(
121
				err,
122
				filesModified,
123
				contextModified,
124
				missingModified,
125
				fileTimestamps,
126
				contextTimestamps,
127
				removedFiles
128
			) => {
129
				this.pausedWatcher = this.watcher;
130
				this.watcher = null;
131
				if (err) {
132
					return this.handler(err);
133
				}
134
				this.compiler.fileTimestamps = fileTimestamps;
135
				this.compiler.contextTimestamps = contextTimestamps;
136
				this.compiler.removedFiles = removedFiles;
137
				if (!this.suspended) {
138
					this._invalidate();
139
				}
140
			},
141
			(fileName, changeTime) => {
142
				this.compiler.hooks.invalid.call(fileName, changeTime);
143
			}
144
		);
145
	}
146

    
147
	invalidate(callback) {
148
		if (callback) {
149
			this.callbacks.push(callback);
150
		}
151
		if (this.watcher) {
152
			this.compiler.fileTimestamps = this.watcher.getFileTimestamps();
153
			this.compiler.contextTimestamps = this.watcher.getContextTimestamps();
154
		}
155
		return this._invalidate();
156
	}
157

    
158
	_invalidate() {
159
		if (this.watcher) {
160
			this.pausedWatcher = this.watcher;
161
			this.watcher.pause();
162
			this.watcher = null;
163
		}
164

    
165
		if (this.running) {
166
			this.invalid = true;
167
			return false;
168
		} else {
169
			this._go();
170
		}
171
	}
172

    
173
	suspend() {
174
		this.suspended = true;
175
		this.invalid = false;
176
	}
177

    
178
	resume() {
179
		if (this.suspended) {
180
			this.suspended = false;
181
			this._invalidate();
182
		}
183
	}
184

    
185
	close(callback) {
186
		const finalCallback = () => {
187
			this.compiler.hooks.watchClose.call();
188
			this.compiler.running = false;
189
			this.compiler.watchMode = false;
190
			if (callback !== undefined) callback();
191
		};
192

    
193
		this.closed = true;
194
		if (this.watcher) {
195
			this.watcher.close();
196
			this.watcher = null;
197
		}
198
		if (this.pausedWatcher) {
199
			this.pausedWatcher.close();
200
			this.pausedWatcher = null;
201
		}
202
		if (this.running) {
203
			this.invalid = true;
204
			this._done = finalCallback;
205
		} else {
206
			finalCallback();
207
		}
208
	}
209
}
210

    
211
module.exports = Watching;
(134-134/144)