diff --git a/package-lock.json b/package-lock.json index d2028ba..1b46d85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8370,6 +8370,12 @@ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -10657,6 +10663,12 @@ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", "dev": true }, + "upath": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", + "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", + "dev": true + }, "update-notifier": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz", @@ -10730,9 +10742,9 @@ } }, "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=" }, "url-parse-lax": { "version": "1.0.0", @@ -10939,26 +10951,15 @@ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, - "watchpack": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", - "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", - "dev": true, - "requires": { - "async": "2.6.0", - "chokidar": "1.7.0", - "graceful-fs": "4.1.11" - } - }, "webpack": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.0.0.tgz", - "integrity": "sha512-wnEjBERuGrbelfsBJ7QKLuGAEaLNPTGJrLgK8H0p1TPS3pUqvTU4OZKeS1OAd8xBpEkuBrFcyHpXPvi0JZVvkA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.1.1.tgz", + "integrity": "sha512-PwxKH81yLjbPyBSZvPj/Ji9pT99XOGFA0t6zipoOKOMNRZ+09N39J5Uzcx3rYKnsHgKwDnfGkvzac4MF2Taknw==", "dev": true, "requires": { "acorn": "5.4.1", "acorn-dynamic-import": "3.0.0", - "ajv": "6.1.1", + "ajv": "6.2.1", "ajv-keywords": "3.1.0", "chrome-trace-event": "0.1.2", "enhanced-resolve": "4.0.0", @@ -10973,14 +10974,14 @@ "schema-utils": "0.4.5", "tapable": "1.0.0", "uglifyjs-webpack-plugin": "1.2.2", - "watchpack": "1.4.0", + "watchpack": "1.5.0", "webpack-sources": "1.1.0" }, "dependencies": { "ajv": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz", - "integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.1.tgz", + "integrity": "sha1-KKarxJOiq+D7TIUHrK7bQ/pVBnE=", "dev": true, "requires": { "fast-deep-equal": "1.0.0", @@ -10988,6 +10989,16 @@ "json-schema-traverse": "0.3.1" } }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "3.1.9", + "normalize-path": "2.1.1" + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -11040,6 +11051,26 @@ } } }, + "chokidar": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", + "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==", + "dev": true, + "requires": { + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.1", + "fsevents": "1.1.3", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.0.4" + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -11151,6 +11182,27 @@ } } }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -11191,6 +11243,21 @@ } } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -11243,20 +11310,31 @@ "snapdragon": "0.8.1", "to-regex": "3.0.2" } + }, + "watchpack": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz", + "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==", + "dev": true, + "requires": { + "chokidar": "2.0.2", + "graceful-fs": "4.1.11", + "neo-async": "2.5.0" + } } } }, "webpack-dev-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", - "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.0.1.tgz", + "integrity": "sha512-JCturcEZNGA0KHEpOJVRTC/VVazTcPfpR9c1Au6NO9a+jxCRchMi87Qe7y3JeOzc0v5eMMKpuGBnPdN52NA+CQ==", "requires": { "loud-rejection": "1.6.0", "memory-fs": "0.4.1", "mime": "2.2.0", "path-is-absolute": "1.0.1", "range-parser": "1.2.0", - "url-join": "2.0.5", + "url-join": "4.0.0", "webpack-log": "1.1.2" }, "dependencies": { diff --git a/package.json b/package.json index 1753d65..0afd07a 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "Use webpack with karma", "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=6.11.5" }, "main": "lib", "files": [ @@ -33,7 +33,7 @@ "loader-utils": "^1.0.0", "lodash": "^4.0.0", "source-map": "^0.5.6", - "webpack-dev-middleware": "^2.0.6" + "webpack-dev-middleware": "^3.0.1" }, "devDependencies": { "babel-cli": "^6.0.0", @@ -55,7 +55,7 @@ "karma-spec-reporter": "^0.0.32", "mocha": "^4.0.0", "standard-version": "^4.0.0", - "webpack": "^4.0.0" + "webpack": "^4.1.1" }, "bugs": "https://github.com/webpack-contrib/karma-webpack/issues", "repository": "https://github.com/webpack-contrib/karma-webpack.git", diff --git a/src/karma-webpack.js b/src/karma-webpack.js index bf98ce7..34f6a4c 100644 --- a/src/karma-webpack.js +++ b/src/karma-webpack.js @@ -20,6 +20,14 @@ var escapeRegExp = function(str) { return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&') } +function invalidate(middleware) { + if (middleware.context.watching) { + return middleware.context.watching.invalidate() + } + + return middleware.invalidate() +} + function Plugin( /* config.webpack */ webpackOptions, /* config.webpackServer */ webpackServerOptions, @@ -75,6 +83,7 @@ function Plugin( this.files = [] this.basePath = basePath this.waiting = [] + this.plugin = {name: 'KarmaWebpack'} var compiler @@ -91,23 +100,56 @@ function Plugin( var applyPlugins = compiler.compilers || [compiler] applyPlugins.forEach(function(compiler) { - compiler.plugin('this-compilation', function(compilation, params) { - compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory) - }) - compiler.plugin('make', this.make.bind(this)) - }, this); + if (compiler.hooks) { + compiler.hooks + .thisCompilation + .tap(this.plugin, (compilation, params) => { + compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory) + }) + compiler.hooks + .make + .tapAsync(this.plugin, this.make.bind(this)) + } else { + compiler.plugin('this-compilation', function(compilation, params) { + compilation.dependencyFactories.set(SingleEntryDependency, params.normalModuleFactory) + }) + compiler.plugin('make', this.make.bind(this)) + } + }, this) + + function handler(callback) { + isBlocked = true + + if (typeof callback === 'function') { + callback(null) + } + } - ['invalid', 'watch-run', 'run'].forEach(function(name) { - compiler.plugin(name, function(_, callback) { - isBlocked = true + var hooks = ['invalid', 'watch-run', 'run'] - if (typeof callback === 'function') { - callback() + if (compiler.hooks) { + hooks = [ + {method: 'sync', name: 'invalid'}, + {method: 'async', name: 'watchRun'}, + {method: 'async', name: 'run'} + ] + } + + hooks.forEach(function(hook) { + if (compiler.hooks) { + if (hook.method === 'sync') { + compiler.hooks[hook.name].tap(this.plugin, () => handler()) + } else { + compiler.hooks[hook.name].tapAsync(this.plugin, (_, callback) => handler(callback)) } - }) - }) + } else { + compiler.plugin(hook, function(_, callback) { + handler(callback) + }) + } + }, this) - compiler.plugin('done', function(stats) { + function done(stats) { var applyStats = Array.isArray(stats.stats) ? stats.stats : [stats] var assets = [] var noAssets = false @@ -139,12 +181,21 @@ function Plugin( blocked[i]() } blocked = [] - }.bind(this)) - compiler.plugin('invalid', function() { + } + + function invalid() { if (!this.waiting) { this.waiting = [] } - }.bind(this)) + } + + if (compiler.hooks) { + compiler.hooks.done.tap(this.plugin, done.bind(this)) + compiler.hooks.invalid.tap(this.plugin, invalid.bind(this)) + } else { + compiler.plugin('done', done.bind(this)) + compiler.plugin('invalid', invalid.bind(this)) + } webpackMiddlewareOptions.publicPath = path.join(os.tmpdir(), '_karma_webpack_', '/') var middleware = this.middleware = new webpackDevMiddleware(compiler, webpackMiddlewareOptions) @@ -197,7 +248,7 @@ Plugin.prototype.make = function(compilation, callback) { this.files = this.files.filter(function(f) { return file !== f }) - this.middleware.invalidate() + invalidate(this.middleware) } callback(err) }.bind(this)) @@ -259,7 +310,7 @@ function createPreprocesor(/* config.basePath */ basePath, webpackPlugin) { return function(content, file, done) { if (webpackPlugin.addFile(file.originalPath)) { // recompile as we have an asset that we have not seen before - webpackPlugin.middleware.invalidate() + invalidate(webpackPlugin.middleware) } // read blocks until bundle is done