mirror of https://github.com/webpack/webpack.git
				
				
				
			Move Watching to its own file
This commit is contained in:
		
							parent
							
								
									7ed2bd2e9b
								
							
						
					
					
						commit
						0014042c53
					
				
							
								
								
									
										158
									
								
								lib/Compiler.js
								
								
								
								
							
							
						
						
									
										158
									
								
								lib/Compiler.js
								
								
								
								
							|  | @ -14,6 +14,7 @@ const AsyncSeriesHook = require("tapable").AsyncSeriesHook; | ||||||
| 
 | 
 | ||||||
| const Compilation = require("./Compilation"); | const Compilation = require("./Compilation"); | ||||||
| const Stats = require("./Stats"); | const Stats = require("./Stats"); | ||||||
|  | const Watching = require("./Watching"); | ||||||
| const NormalModuleFactory = require("./NormalModuleFactory"); | const NormalModuleFactory = require("./NormalModuleFactory"); | ||||||
| const ContextModuleFactory = require("./ContextModuleFactory"); | const ContextModuleFactory = require("./ContextModuleFactory"); | ||||||
| const ResolverFactory = require("./ResolverFactory"); | const ResolverFactory = require("./ResolverFactory"); | ||||||
|  | @ -21,159 +22,6 @@ const ResolverFactory = require("./ResolverFactory"); | ||||||
| const RequestShortener = require("./RequestShortener"); | const RequestShortener = require("./RequestShortener"); | ||||||
| const makePathsRelative = require("./util/identifier").makePathsRelative; | const makePathsRelative = require("./util/identifier").makePathsRelative; | ||||||
| 
 | 
 | ||||||
| class Watching { |  | ||||||
| 	constructor(compiler, watchOptions, handler) { |  | ||||||
| 		this.startTime = null; |  | ||||||
| 		this.invalid = false; |  | ||||||
| 		this.handler = handler; |  | ||||||
| 		this.callbacks = []; |  | ||||||
| 		this.closed = 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.call(stats); |  | ||||||
| 
 |  | ||||||
| 							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.call(stats); |  | ||||||
| 		this.handler(null, stats); |  | ||||||
| 		if(!this.closed) { |  | ||||||
| 			this.watch(Array.from(compilation.fileDependencies), Array.from(compilation.contextDependencies), Array.from(compilation.missingDependencies)); |  | ||||||
| 		} |  | ||||||
| 		this.callbacks.forEach(cb => 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) => { |  | ||||||
| 			this.pausedWatcher = this.watcher; |  | ||||||
| 			this.watcher = null; |  | ||||||
| 			if(err) return this.handler(err); |  | ||||||
| 
 |  | ||||||
| 			this.compiler.fileTimestamps = fileTimestamps; |  | ||||||
| 			this.compiler.contextTimestamps = contextTimestamps; |  | ||||||
| 			this.invalidate(); |  | ||||||
| 		}, (fileName, changeTime) => { |  | ||||||
| 			this.compiler.hooks.invalid.call(fileName, changeTime); |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	invalidate(callback) { |  | ||||||
| 		if(callback) { |  | ||||||
| 			this.callbacks.push(callback); |  | ||||||
| 		} |  | ||||||
| 		if(this.watcher) { |  | ||||||
| 			this.pausedWatcher = this.watcher; |  | ||||||
| 			this.watcher.pause(); |  | ||||||
| 			this.watcher = null; |  | ||||||
| 		} |  | ||||||
| 		if(this.running) { |  | ||||||
| 			this.invalid = true; |  | ||||||
| 			return false; |  | ||||||
| 		} else { |  | ||||||
| 			this._go(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	close(callback) { |  | ||||||
| 		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 = () => { |  | ||||||
| 				this.compiler.hooks.watchClose.call(); |  | ||||||
| 				callback(); |  | ||||||
| 			}; |  | ||||||
| 		} else { |  | ||||||
| 			this.compiler.hooks.watchClose.call(); |  | ||||||
| 			callback(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| class Compiler extends Tapable { | class Compiler extends Tapable { | ||||||
| 	constructor(context) { | 	constructor(context) { | ||||||
| 		super(); | 		super(); | ||||||
|  | @ -331,8 +179,7 @@ class Compiler extends Tapable { | ||||||
| 	watch(watchOptions, handler) { | 	watch(watchOptions, handler) { | ||||||
| 		this.fileTimestamps = {}; | 		this.fileTimestamps = {}; | ||||||
| 		this.contextTimestamps = {}; | 		this.contextTimestamps = {}; | ||||||
| 		const watching = new Watching(this, watchOptions, handler); | 		return new Watching(this, watchOptions, handler); | ||||||
| 		return watching; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	run(callback) { | 	run(callback) { | ||||||
|  | @ -626,5 +473,4 @@ class Compiler extends Tapable { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Compiler.Watching = Watching; |  | ||||||
| module.exports = Compiler; | module.exports = Compiler; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,162 @@ | ||||||
|  | /* | ||||||
|  | 	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; | ||||||
|  | 		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.call(stats); | ||||||
|  | 
 | ||||||
|  | 							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.call(stats); | ||||||
|  | 		this.handler(null, stats); | ||||||
|  | 		if(!this.closed) { | ||||||
|  | 			this.watch(Array.from(compilation.fileDependencies), Array.from(compilation.contextDependencies), Array.from(compilation.missingDependencies)); | ||||||
|  | 		} | ||||||
|  | 		this.callbacks.forEach(cb => 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) => { | ||||||
|  | 			this.pausedWatcher = this.watcher; | ||||||
|  | 			this.watcher = null; | ||||||
|  | 			if(err) return this.handler(err); | ||||||
|  | 
 | ||||||
|  | 			this.compiler.fileTimestamps = fileTimestamps; | ||||||
|  | 			this.compiler.contextTimestamps = contextTimestamps; | ||||||
|  | 			this.invalidate(); | ||||||
|  | 		}, (fileName, changeTime) => { | ||||||
|  | 			this.compiler.hooks.invalid.call(fileName, changeTime); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	invalidate(callback) { | ||||||
|  | 		if(callback) { | ||||||
|  | 			this.callbacks.push(callback); | ||||||
|  | 		} | ||||||
|  | 		if(this.watcher) { | ||||||
|  | 			this.pausedWatcher = this.watcher; | ||||||
|  | 			this.watcher.pause(); | ||||||
|  | 			this.watcher = null; | ||||||
|  | 		} | ||||||
|  | 		if(this.running) { | ||||||
|  | 			this.invalid = true; | ||||||
|  | 			return false; | ||||||
|  | 		} else { | ||||||
|  | 			this._go(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	close(callback) { | ||||||
|  | 		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 = () => { | ||||||
|  | 				this.compiler.hooks.watchClose.call(); | ||||||
|  | 				callback(); | ||||||
|  | 			}; | ||||||
|  | 		} else { | ||||||
|  | 			this.compiler.hooks.watchClose.call(); | ||||||
|  | 			callback(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = Watching; | ||||||
|  | @ -7,7 +7,6 @@ const sinon = require("sinon"); | ||||||
| 
 | 
 | ||||||
| const webpack = require("../"); | const webpack = require("../"); | ||||||
| const WebpackOptionsDefaulter = require("../lib/WebpackOptionsDefaulter"); | const WebpackOptionsDefaulter = require("../lib/WebpackOptionsDefaulter"); | ||||||
| const Compiler = require("../lib/Compiler"); |  | ||||||
| const MemoryFs = require("memory-fs"); | const MemoryFs = require("memory-fs"); | ||||||
| 
 | 
 | ||||||
| describe("Compiler", () => { | describe("Compiler", () => { | ||||||
|  | @ -273,14 +272,6 @@ describe("Compiler", () => { | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 		describe("static method", () => { |  | ||||||
| 			it("should have an method, Watching", (done) => { |  | ||||||
| 				const actual = new Compiler.Watching(compiler, 1000, err => err); |  | ||||||
| 				actual.running.should.be.exactly(true); |  | ||||||
| 				actual.constructor.name.should.be.exactly("Watching"); |  | ||||||
| 				done(); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		describe("constructor", () => { | 		describe("constructor", () => { | ||||||
| 			it("constructs Watching.watchOptions correctly when passed a number, string, or object for watchOptions", (done) => { | 			it("constructs Watching.watchOptions correctly when passed a number, string, or object for watchOptions", (done) => { | ||||||
| 				const Watching1 = compiler.watch(1000, err => err); | 				const Watching1 = compiler.watch(1000, err => err); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue