Skip to content

Instantly share code, notes, and snippets.

@mvgijssel
Last active August 27, 2019 10:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mvgijssel/d3b121ad50e34c09a124 to your computer and use it in GitHub Desktop.
Save mvgijssel/d3b121ad50e34c09a124 to your computer and use it in GitHub Desktop.
/*
* This plugin makes sure karma doesn't run any specs when there's a
* compilation error in a module by including a module even if the module has errors.
*
* Webpack's normal behaviour is to not include modules which have errors,
* which causes Karma to run all the tests without the failed spec.
*
* Some links to where this magic actually happens in Webpack:
*
* The module will be removed from the dependency:
* https://github.com/webpack/webpack/blob/v1.12.14/lib/Compilation.js#L646-L649
*
* and dependencies without a module won't be included in the module map:
* https://github.com/webpack/webpack/blob/v1.12.14/lib/ContextModule.js#L87-L89
*
* Setting the module._source to a javascript error is copied from:
* https://github.com/webpack/webpack/blob/v1.12.14/lib/NormalModule.js#L127
*/
var WebpackKarmaWarningsPlugin = function() {};
var RawSource = require("webpack-core/lib/RawSource");
WebpackKarmaWarningsPlugin.prototype.apply = function(compiler) {
compiler.plugin("compilation", function(compilation) {
compilation.plugin("failed-module", function(module) {
var moduleErrorMessage = module.error.error.toString()
module._source = new RawSource(`throw new Error(${JSON.stringify(moduleErrorMessage)});`);
module.error = null;
});
});
};
module.exports = WebpackKarmaWarningsPlugin;
@ertrzyiks
Copy link

ertrzyiks commented May 31, 2016

You could stringify an error message to be sure its valid literal string value. If the message contains quote mark ', there is a syntax error instead of the original message.

module._source = new RawSource(`throw new Error(${JSON.stringify(moduleErrorMessage)});`);

@mvgijssel
Copy link
Author

Ah great suggestion! Thanks!

@morsdyce
Copy link

morsdyce commented Sep 8, 2016

@mvgijssel Would you mind publishing this on npm?
If it's too much trouble I have no problem doing it and crediting you.

Thanks

@bradleyayers
Copy link

Something on NPM would be great for open source projects, as it means they don't need to copy/paste and deal with licensing this snippet.

@mealeyst
Copy link

mealeyst commented Sep 28, 2016

@mvgijssel I apologize for being a complete webpack noob here... I grabbed this code and tossed it into my webpack plugins:

webpackConfig.plugins = [
  new WebpackKarmaWarningsPlugin(),
  new webpack.DefinePlugin(config.globals),
  new HtmlWebpackPlugin({
    template: paths.client('index.html'),
    hash: false,
    favicon: paths.client('static/favicon.ico'),
    filename: 'index.html',
    inject: 'body',
    minify: {
      collapseWhitespace: true
    }
  })
]

When adding console.logs inside of the compiler.plugin() I can see that compiler plugin is firing however when adding a console.log inside of the compilation.plugin() function, it doesn't appear to be firing. Am I doing something wrong???

EDIT: Another thing to note, I am not sure if this is important, our test specs aren't being included due to syntax errors or issues such as when a file that is imported in a spec's name is changed, I don't know if that prevents the failed-module compilation instance to not fire, my assumptions was that it would.

EDIT: So I did some more digging and the error that I am seeing might not be related to webpack but to karma instead, I am now trying to track down on how to force Karma to fail on syntax errors, it looks like others have run into this issue as see here though it doesn't sound like their solution was something that they were happy with.

UPDATE: So I once again started doing some more digging and I found that the solution posted by Stuk found here actually did work for me, with the exception of throwing an error as was mentioned in the thread of comments that led me to this gist. Is there any reason why that gist seems to fire while the compilation.plugin() function in your gist doesn't fire?

@yuanfeiz
Copy link

yuanfeiz commented Oct 9, 2016

With what changes does it work in webpack v2.0?

@mvgijssel
Copy link
Author

So sorry for not replying, for some reason I'm not getting gist notifications 🙈. Not sure if it helps anyone, but we require karma specs as follows using a context require:

var context = require.context(".", true, /_spec$/);
context.keys().forEach(context);

The webpack plugins for running karma

  plugins: [
    new webpack.DefinePlugin({
      NODE_TEST: true,
    }),
    new WebpackConsoleLogPlugin(),
    new WebpackKarmaWarningsPlugin(),
    new LoaderOptionsPlugin({
      debug: true,
    }),
  ],

Some of the versions:

  • webpack 2.2.1
  • karma 1.4.1
  • karma-webpack 2.0.2

@mvgijssel Would you mind publishing this on npm?
If it's too much trouble I have no problem doing it and crediting you. Thanks

Something on NPM would be great for open source projects, as it means they don't need to copy/paste and deal with licensing this snippet.

I'll publish this on npm if people are still using this!

When adding console.logs inside of the compiler.plugin() I can see that compiler plugin is firing however when adding a console.log inside of the compilation.plugin() function, it doesn't appear to be firing. Am I doing something wrong???

No clue :/. Do you use the same versions / require strategy?

EDIT: Another thing to note, I am not sure if this is important, our test specs aren't being included due to syntax errors or issues such as when a file that is imported in a spec's name is changed, I don't know if that prevents the failed-module compilation instance to not fire, my assumptions was that it would.

Do you use the same plugins in the same order? Also do you include the NoErrorsPlugin? Maybe that's preventing stuff from firing?

With what changes does it work in webpack v2.0?
We use webpack v2 and it seems to work just fine!

@aszmyd
Copy link

aszmyd commented Apr 20, 2018

Any chance it could work with webpack@3 ?
I get this error using webpack@3.10.0:

20 04 2018 06:56:55.348:ERROR [config]: Invalid config file!
    Error: Cannot find module 'webpack-core/lib/RawSource'

@petergaal91
Copy link

@aszmyd Use this: const RawSource = require("webpack-sources").RawSource;

@jonesmac
Copy link

for those looking for a webpack 4 approach in typescript - https://gist.github.com/jonesmac/9ef456153c714db56be0ec24b61c6fbb

I found I had to use the compilation.warnings.length to test if a relevant error occurred. I tried the failedModule hook but with no success.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment