-
Notifications
You must be signed in to change notification settings - Fork 220
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(karma-webpack): Add webpack as framework and use shared bundles (#…
…380) Closes #379 BREAKING CHANGE: webpack needs to be added to frameworks ``` // old: frameworks: ['mocha'], // new: frameworks: ['mocha', 'webpack'], ``` BREAKING CHANGE: old alternative usage is no longer recommended BREAKING CHANGE: webpack-dev-middleware removed BREAKING CHANGE: default webpack configuration changed drastically
- Loading branch information
1 parent
e207fe5
commit 2ab7ad5
Showing
12 changed files
with
3,231 additions
and
3,399 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
.eslintcache | ||
|
||
lib | ||
coverage | ||
node_modules | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/* eslint-disable no-console */ | ||
|
||
const path = require('path'); | ||
const fs = require('fs'); | ||
const os = require('os'); | ||
|
||
const webpack = require('webpack'); | ||
const merge = require('webpack-merge'); | ||
|
||
class KarmaSyncPlugin { | ||
constructor(options) { | ||
this.karmaEmitter = options.karmaEmitter; | ||
this.controller = options.controller; | ||
} | ||
|
||
apply(compiler) { | ||
this.compiler = compiler; | ||
|
||
// webpack bundles are finished | ||
compiler.hooks.done.tap('KarmaSyncPlugin', async (stats) => { | ||
// read generated file content and store for karma preprocessor | ||
this.controller.bundlesContent = {}; | ||
stats.toJson().assets.forEach((webpackFileObj) => { | ||
const filePath = `${compiler.options.output.path}/${ | ||
webpackFileObj.name | ||
}`; | ||
this.controller.bundlesContent[webpackFileObj.name] = fs.readFileSync( | ||
filePath, | ||
'utf-8' | ||
); | ||
}); | ||
|
||
// karma refresh | ||
this.karmaEmitter.refreshFiles(); | ||
}); | ||
} | ||
} | ||
|
||
const defaultWebpackOptions = { | ||
mode: 'development', | ||
output: { | ||
filename: '[name].js', | ||
path: path.join(os.tmpdir(), '_karma_webpack_'), | ||
}, | ||
stats: { | ||
modules: false, | ||
colors: true, | ||
}, | ||
watch: false, | ||
optimization: { | ||
runtimeChunk: 'single', | ||
splitChunks: { | ||
chunks: 'all', | ||
minSize: 0, | ||
cacheGroups: { | ||
commons: { | ||
name: 'commons', | ||
chunks: 'initial', | ||
minChunks: 1, | ||
}, | ||
}, | ||
}, | ||
}, | ||
plugins: [], | ||
// Something like this will be auto added by this.configure() | ||
// entry: { | ||
// 'foo-one.test.js': 'path/to/test/foo-one.test.js', | ||
// 'foo-two.test.js': 'path/to/test/foo-two.test.js', | ||
// }, | ||
// plugins: [ | ||
// new KarmaSyncPlugin() | ||
// ], | ||
}; | ||
|
||
class KarmaWebpackController { | ||
set webpackOptions(options) { | ||
this.__webpackOptions = options; | ||
} | ||
|
||
get webpackOptions() { | ||
return this.__webpackOptions; | ||
} | ||
|
||
set karmaEmitter(emitter) { | ||
this.__karmaEmitter = emitter; | ||
|
||
this.__webpackOptions.plugins.push( | ||
new KarmaSyncPlugin({ | ||
karmaEmitter: emitter, | ||
controller: this, | ||
}) | ||
); | ||
|
||
emitter.on('exit', (done) => { | ||
this.onKarmaExit(); | ||
done(); | ||
}); | ||
} | ||
|
||
get karmaEmitter() { | ||
return this.__karmaEmitter; | ||
} | ||
|
||
get outputPath() { | ||
return this.webpackOptions.output.path; | ||
} | ||
|
||
constructor() { | ||
this.isActive = false; | ||
this.bundlesContent = {}; | ||
this.__debounce = false; | ||
this.webpackOptions = defaultWebpackOptions; | ||
} | ||
|
||
updateWebpackOptions(newOptions) { | ||
this.webpackOptions = merge(this.webpackOptions, newOptions); | ||
} | ||
|
||
async bundle() { | ||
if (this.isActive === false && this.__debounce === false) { | ||
console.log('Webpack bundling...'); | ||
this._activePromise = this._bundle(); | ||
} | ||
return this._activePromise; | ||
} | ||
|
||
async _bundle() { | ||
this.isActive = true; | ||
this.__debounce = true; | ||
this.compiler = webpack(this.webpackOptions); | ||
return new Promise((resolve) => { | ||
if (this.webpackOptions.watch === true) { | ||
console.log('Webpack starts watching...'); | ||
this.webpackFileWatcher = this.compiler.watch({}, (err, stats) => | ||
this.handleBuildResult(err, stats, resolve) | ||
); | ||
} else { | ||
this.compiler.run((err, stats) => | ||
this.handleBuildResult(err, stats, resolve) | ||
); | ||
} | ||
}); | ||
} | ||
|
||
handleBuildResult(err, stats, resolve) { | ||
if (err) { | ||
console.error(err.stack || err); | ||
if (err.details) { | ||
console.error(err.details); | ||
} | ||
return; | ||
} | ||
|
||
const info = stats.toJson(); | ||
if (stats.hasErrors()) { | ||
console.error(info.errors); | ||
} | ||
if (stats.hasWarnings()) { | ||
console.warn(info.warnings); | ||
} | ||
|
||
this.__debounce = setTimeout(() => (this.__debounce = false), 100); | ||
this.isActive = false; | ||
|
||
console.log(stats.toString(this.webpackOptions.stats)); | ||
resolve(); | ||
} | ||
|
||
onKarmaExit() { | ||
if (this.webpackFileWatcher) { | ||
this.webpackFileWatcher.close(); | ||
console.log('Webpack stopped watching.'); | ||
} | ||
} | ||
} | ||
|
||
module.exports = { | ||
KarmaSyncPlugin, | ||
KarmaWebpackController, | ||
defaultWebpackOptions, | ||
}; |
File renamed without changes.
Oops, something went wrong.