Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow rebuilds #54

Closed
jhollingworth opened this issue Jun 16, 2015 · 39 comments
Closed

Slow rebuilds #54

jhollingworth opened this issue Jun 16, 2015 · 39 comments

Comments

@jhollingworth
Copy link

I'm finding re-builds are taking much longer than I'd like. Right now it takes around 6-7s between me saving a file and the tests actually running. This is compared to ~500ms when WebPack is watching files. We saw some speed up with the suggested alternative usage but there's still an annoying delay.

Any thoughts on how to improve this? Or is this fundamental to Karma?

@kevinold
Copy link

I'm seeing the same issue. I have sourcemaps enabled so I know there is a performance hit there. I'm seeing 10-15s build times for about 40 files and of course their required node modules. I'd love to take advantage of a vendor bundle like I do in production but doesn't seem supported.

@vojto
Copy link

vojto commented Aug 19, 2015

I'm currently at 5s. It's really frustrating. How is everybody esle dealing with this?

@jhollingworth
Copy link
Author

I gave up and moved to node with jsdom. so much nicer

@leoselig
Copy link

leoselig commented Sep 1, 2015

+1
The rebuild time is unacceptable for a typical TDD workflow
We are experiencing this even in a medium sized project

@vojto
Copy link

vojto commented Sep 1, 2015

It shouldn't be that hard to implement. Just need to somehow hook into Webpack's incremental building (what happens when you run --watch). I'll give it a try when I find some time.

@eknuth
Copy link

eknuth commented Oct 5, 2015

Would definitely love to see this!

@eknuth
Copy link

eknuth commented Oct 5, 2015

Sorry intended to comment with my workaround. I am running weback with --watch as a separate process and not using karma to build :(

@aaronjensen
Copy link
Collaborator

check out https://www.npmjs.com/package/karma-webpack-with-fast-source-maps https://github.com/aaronjensen/karma-webpack

our builds run in a few hundred ms, and it only runs the tests it needs to

@eknuth
Copy link

eknuth commented Oct 9, 2015

@aaronjensen that is incredible, thank you so much!

@aaronjensen
Copy link
Collaborator

You bet.

@leoselig
Copy link

Nice!
Any chance this becomes a PR soon? :)

@aaronjensen
Copy link
Collaborator

@leoselig maybe, @sokra is on vacation, we can discuss when he gets back. I'd love to have it in, but it removes some features (that don't appear to work any way-- #77)

@aaronjensen
Copy link
Collaborator

also, part of it is a pull already: #76

@tarjei
Copy link

tarjei commented Oct 16, 2015

You, my friend @aaronjensen, is the best thing since the invention of electricity!

I'm really looking forward to the day four fork is merged into webpack-karma mainline.

Great work!

@necolas
Copy link

necolas commented Oct 27, 2015

That's really nice @aaronjensen! Thanks. I ended up using your fork and creating a helper function to encapsulate the entry file boilerplate it depends on. Our entry file looks a bit like this:

const hotLoader = require('./tools/hotTestLoader')
hotLoader(require.context(/* etc /*))

@necolas
Copy link

necolas commented Nov 8, 2015

@aaronjensen FYI, your package stopped working from karma@>=0.13.11. (Your repo doesn't have issues enabled).

@aaronjensen
Copy link
Collaborator

@necolas It works for me w/ 0.13.15. What problem are you seeing?

@necolas
Copy link

necolas commented Nov 9, 2015

When a file changes, it reruns 0 tests with every version of karma >= 0.13.1. I've moved the boilerplate into a function that is called with the webpack require.context.

// hotloader.js
module.exports = function hotLoader(context) {
  const __karmaWebpackManifest__ = [];

  function inManifest(path) {
    return __karmaWebpackManifest__.indexOf(path) >= 0;
  }

  let runnable = context.keys().filter(inManifest);
  // Run all tests if we didn't find any changes
  if (!runnable.length) { runnable = context.keys(); }
  runnable.forEach(context);
};

// entry
hotLoader(require.context(...))

@aaronjensen
Copy link
Collaborator

@necolas sorry, can't reproduce. Try the most simple case in your entry:

const __karmaWebpackManifest__ = [];

require('./specHelper');
const testsContext = require.context('.', true, /\/(?!(flycheck))[^/]+\.spec$/);

function inManifest(path) {
  return __karmaWebpackManifest__.indexOf(path) >= 0;
}

let runnable = testsContext.keys().filter(inManifest);
if (!runnable.length) {
  runnable = testsContext.keys();
}

runnable.forEach(testsContext);

@aaronjensen
Copy link
Collaborator

Actually, yes, I believe that's what the problem is. I actually replace __karmaWebpackManifest__ with the actual manifest in webpack, so moving it out of your entry probably won't work.

@necolas
Copy link

necolas commented Nov 9, 2015

Hmm, it had been working and works with some versions of Karma.

@necolas
Copy link

necolas commented Nov 9, 2015

Tried inlining everything in my entry file and I have the same problem. I'm using webpack 1.12.2

@tarjei
Copy link

tarjei commented Nov 18, 2015

@aaronjensen would it be possible to add a way to signal to karma (via a kill signal or some http url) so that I can get karma to run all the tests without restarting karma?

@eknuth
Copy link

eknuth commented Nov 18, 2015

@tarjei touching or saving your test entry point will run all the tests.

@maksimr
Copy link

maksimr commented Mar 19, 2016

@aaronjensen https://www.npmjs.com/package/karma-webpack-with-fast-source-maps is a great plugin which really speed up tests. I think it should be part of karma-webpack.
What do you think?

@aaronjensen
Copy link
Collaborator

@maksimr i'm all for it, I just haven't had a lot of time to make it so. I'm also still not entirely clear on some of the changes I made, like with the multiple configurations.

@maksimr
Copy link

maksimr commented Mar 19, 2016

@aaronjensen I see. My opinion If you push current solution to the karma-webpack we can understand what people use and community will faster fix karma-webpack then your fork. Maybe they simple does not use multiple configuration. :)

Thanks

@joshwiens
Copy link
Contributor

//cc @MikaAK

@lucassus
Copy link

It's not directly related to karma-webpack but this https://github.com/lucassus/angular-webpack-seed/pull/51/files PR demonstrates how I workaround slow rebuild problem.
Basically in the first terminal I run webpack watcher, in the configuration I have two chunks - vendor, app + specs and in the second terminal I'm running karma watcher against the generated files.

Rebuild speed in this case is almost x5 better, perfect for TDD ;)

@tarjei
Copy link

tarjei commented Nov 17, 2016

Very interesting!

2016-11-17 13:35 GMT+01:00 Lukasz Bandzarewicz notifications@github.com:

It's not directly related to karma-webpack but this
https://github.com/lucassus/angular-webpack-seed/pull/51/files PR
demonstrates how I workaround slow rebuild problem.
Basically in the first terminal I run webpack watcher, in the
configuration I have two chunks - vendor, app + specs and in the second
terminal I'm running karma watcher against the generated files.

Rebuild speed in this case is almost x5 better, perfect for TDD ;)


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#54 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAM5PxNcQb3WdBDpOQzqfMfjCwXJpMrnks5q_EodgaJpZM4FEZuQ
.


Tarjei Huse
Mobil: 920 63 413

@joshwiens joshwiens added this to the 3.0.0-alpha.0 milestone Jan 16, 2017
@joshwiens joshwiens removed the discuss label Jan 16, 2017
@pjtatlow
Copy link

pjtatlow commented Mar 6, 2018

@aaronjensen Is there any hope of your changes in karma-webpack-with-fast-source-maps getting merged into karma-webpack? It seems like it's been a while and I want to know if there's anything I can do to help.

@aaronjensen
Copy link
Collaborator

@pjtatlow We don't use Karma anymore and I believe karma-webpack has changed a bit since my fork. I'm sure they would welcome a PR w/ my changes to the current karma-webpack.

@GalitTugi
Copy link

@aaronjensen 's solution worked for me!
from 18-20 seconds the rebuild scaled down to about 1s!!
The solution for me was in this link: https://github.com/aaronjensen/karma-webpack

Thanks @aaronjensen !

@fzxt
Copy link

fzxt commented Sep 4, 2018

I'm currently running webpack-dev-server on the side to build my test bundle then telling Karma to watch the output bundle for changes.

@dannybloe
Copy link

Any news regarding this problem? It is almost impossible for me to have karma watch for changes as recompiling takes ages. It's always faster to just break and restart the tests.

@maksimr
Copy link

maksimr commented Nov 18, 2019

@dannybloe we are currently using this workaround

karma.config.js

  webpackConf.plugins = webpackConf.plugins.concat(
    (new class {
      apply(compiler) {
        const name = 'YouTrackKarmaAffectedTestsPlugin';
        const {ConcatSource} = require('webpack-sources');
        compiler.hooks.compilation.tap(name, compilation => {
          compilation.hooks.optimizeChunkAssets.tap(name, chunks => {
            const affected = compilation.modules.reduce((affected, module) => {
              if (module.built && !affected.has(module.id)) {
                affected.add(module.id);
                const queue = module.reasons.map((reason) => reason.module);
                while (queue.length) {
                  const module = queue.shift();
                  if (module && !affected.has(module.id)) {
                    affected.add(module.id);
                    // eslint-disable-next-line max-depth
                    for (const reason of module.reasons) {
                      queue.push(reason.module);
                    }
                  }
                }
              }
              return affected;
              // eslint-disable-next-line no-undef
            }, new Set());


            const karmaWebpackManifest = JSON.stringify(Array.from(affected));
            for (const chunk of chunks) {
              for (const file of chunk.files) {
                compilation.assets[file] = new ConcatSource(
                  `this.karmaWebpackManifest = ${karmaWebpackManifest};`,
                  '\n',
                  compilation.assets[file]);
              }
            }
          });
        });
      }
    }())
  );

test-bundle.js

const testsContext = require.context('../../app', true, /test\/(?!e2e\/).*\.js$/);
const allTests = testsContext.keys();
const affectedTests = global.karmaWebpackManifest ?
  allTests.filter((path) => global.karmaWebpackManifest.indexOf(testsContext.resolve(path)) >= 0) :
  null;

(affectedTests && affectedTests.length ?
  affectedTests :
  allTests).forEach(testsContext);

So this code allows us to run only tests affected by changes.

global.karmaWebpackManifest- This global variable contains a list of files affected by changes. We inject this variable by webpack plugin (described above)

@dannybloe
Copy link

Mm, looks complicated 😉
Does this solve the issue where, upon a code change, Webpack quickly runs to 89% of the compilation process and then seems to wait for a couple of minutes before it continues (and run the tests)?

@codymikol codymikol removed this from the 4.0.0 milestone Feb 3, 2021
@codymikol
Copy link
Owner

I'll test this on a large project and see if there is still a significant slowdown.

@codymikol
Copy link
Owner

As karma is now deprecated and coming up on EOL, we are no longer planning on any significant enhancements to this project and are instead going to focus on security updates, stability, and a migration path forward as karma's lifecycle comes to an end.

Thank you for supporting and using this project!

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

No branches or pull requests