karma-runner / karma

Spectacular Test Runner for JavaScript
http://karma-runner.github.io
MIT License
11.95k stars 1.71k forks source link

Feature request: functions/URLs as file sources #2774

Open filipesilva opened 7 years ago

filipesilva commented 7 years ago

I'd like to propose allowing functions or URLs as file sources:

files: [
  (done) => promisifiedHttpGet( 'http://localhost:8080/bundle.js').then(resp => done(resp))
  (done) => done('<script> console.log('dynamic script content') </script)')
]
files: [
  'http://localhost:8080/vendor.js'
  'http://localhost:8080/bundle.js'
]

Currently this is not possible. Each entry in the files array must correspond to a real file in the file system.

If such a feature was to be added, a plugin for karma could dynamically fill in the files array upon compilation (when it knows what files were output), and notify Karma that it needs to reload.

This would help with a problem I've been having while trying to improve the performance of https://github.com/webpack-contrib/karma-webpack, in which an entry might originate multiple bundles.

The multiple bundles are important for build performance. Automatically making a bundle for vendor files massively cuts down the recompile time of tests proper.

I did something similar in https://github.com/angular/angular-cli/pull/6160, and observed 15x smaller build times (16.5s to 0.9s) on a medium sized project.

Since there was no way of adding the Webpack URLs directly to the files array, instead I added a custom karma-context.html that had hardcoded script tags. Then I added a custom handler to serve those files from the webpack middleware.

The one big problem with this approach is that the hardcoded files are not processed by Karma, which at least means that sourcemaps become problematic (https://github.com/angular/angular-cli/issues/6583).

Another problem is that the possible list of files has to be known at library build time, and that using another custom context file will break functionality.

I feel it would be a worthwhile addition to Karma.

There's a couple of open questions about it though:

Please let me know what you think of this proposal. If there is a better way of achieving the dynamic 'virtual' files list, I'm all for it.

/cc @d3viant0ne

joshwiens commented 7 years ago

We have been beating our faces against the keyboard trying to come up with a good way to do this in webpack-contrib as well and we are happy to throw resources at the problem if we can come up with a viable solution everyone agrees on.

dignifiedquire commented 7 years ago

Thank you for the proposal. I am very open to doing this, but will need to figure out how to make this work well. One random idea is to require those files be an EventEmitter which emits events if it is changed. Not a 100% sure though.

filipesilva commented 7 years ago

An event emitter sounds like a good idea, yes. It would make the watching trivial, and also allow for dynamic content. I think it would address the main requirements.

I'm unfamiliar with the inner workings of Karma proper though, so it's hard for me to say what would go well in the current architecture.

Is it currently possible to dynamically add more files to the file array during runtime? Depending on how code is split, new bundles might be formed during rebuilds.