Skip to content

Commit 6ef7e7b

Browse files
committed
feat(config): add nocache option for file patterns
Add nocache property for file patterns in the config file. This allows files that should be served by the webserver but that don't need to be preprocessed but that should to be served fresh (e.g. map files, pre-transpiled source built by other build process) without a large amount of watches.
1 parent b8e1bf1 commit 6ef7e7b

7 files changed

Lines changed: 78 additions & 17 deletions

File tree

docs/config/02-files.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ Each pattern is either a simple string or an object with four properties:
4141
* **Default.** `true`
4242
* **Description.** Should the files be served by Karma's webserver?
4343

44+
### `nocache`
45+
* **Type.** Boolean
46+
* **Default.** `false`
47+
* **Description.** Should the files be served from disk on each request by Karma's webserver?
48+
4449

4550
## Preprocessor transformations
4651
Depending on preprocessor configuration, be aware that files loaded may be transformed and no longer available in
@@ -62,7 +67,10 @@ files: [
6267
{pattern: 'compiled/index.html', watched: false},
6368

6469
// this file only gets watched and is otherwise ignored
65-
{pattern: 'app/index.html', included: false, served: false}
70+
{pattern: 'app/index.html', included: false, served: false},
71+
72+
// this file will be served on demand from disk and will be ignored by the watcher
73+
{pattern: 'compiled/app.js.map', included: false, served: true, watched: false, nocache: true}
6674
],
6775
```
6876

@@ -73,7 +81,7 @@ Example for loading images
7381

7482
```javascript
7583
files: [
76-
{pattern: "test/images/*.jpg", watched: false, included: false, served: true}
84+
{pattern: 'test/images/*.jpg', watched: false, included: false, served: true, nocache: false}
7785
],
7886
```
7987

lib/config.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ try {
2222
LIVE_SCRIPT_AVAILABLE = true;
2323
} catch (e) {}
2424

25-
var Pattern = function(pattern, served, included, watched) {
25+
var Pattern = function(pattern, served, included, watched, nocache) {
2626
this.pattern = pattern;
2727
this.served = helper.isDefined(served) ? served : true;
2828
this.included = helper.isDefined(included) ? included : true;
2929
this.watched = helper.isDefined(watched) ? watched : true;
30+
this.nocache = helper.isDefined(nocache) ? nocache : false;
3031
};
3132

3233
var UrlPattern = function(url) {
33-
Pattern.call(this, url, false, true, false);
34+
Pattern.call(this, url, false, true, false, false);
3435
};
3536

3637

@@ -43,15 +44,20 @@ var createPatternObject = function(pattern) {
4344
if (pattern.pattern && helper.isString(pattern.pattern)) {
4445
return helper.isUrlAbsolute(pattern.pattern) ?
4546
new UrlPattern(pattern.pattern) :
46-
new Pattern(pattern.pattern, pattern.served, pattern.included, pattern.watched);
47+
new Pattern(
48+
pattern.pattern,
49+
pattern.served,
50+
pattern.included,
51+
pattern.watched,
52+
pattern.nocache);
4753
}
4854

4955
log.warn('Invalid pattern %s!\n\tObject is missing "pattern" property.', pattern);
50-
return new Pattern(null, false, false, false);
56+
return new Pattern(null, false, false, false, false);
5157
}
5258

5359
log.warn('Invalid pattern %s!\n\tExpected string or object with "pattern" property.', pattern);
54-
return new Pattern(null, false, false, false);
60+
return new Pattern(null, false, false, false, false);
5561
};
5662

5763

lib/file_list.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ var File = function(path, mtime) {
3232

3333
this.mtime = mtime;
3434
this.isUrl = false;
35+
36+
this.doNotCache = false;
3537
};
3638

3739
var Url = function(path) {
@@ -102,6 +104,10 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
102104
files.included.push(file);
103105
}
104106

107+
if (patterns[idx].nocache) {
108+
file.doNotCache = true;
109+
}
110+
105111
uniqueMap[file.path] = true;
106112
}
107113
});
@@ -216,15 +222,24 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
216222
// TODO(vojta): reuse file objects
217223
var file = new File(path, stat.mtime);
218224

219-
preprocess(file, function(err) {
220-
buckets[i].push(file);
225+
if (patternObject.nocache) {
226+
log.debug('Not preprocessing "%s" due to nocache', path);
221227

222-
if (err) {
223-
addError(path);
224-
}
228+
file.doNotCache = true;
229+
buckets[i].push(file);
225230

226231
finish();
227-
});
232+
} else {
233+
preprocess(file, function(err) {
234+
buckets[i].push(file);
235+
236+
if (err) {
237+
addError(path);
238+
}
239+
240+
finish();
241+
});
242+
}
228243
} else {
229244
log.debug('Ignored directory "%s"', path);
230245
finish();

lib/middleware/common.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var serve404 = function(response, path) {
2828
var createServeFile = function(fs, directory) {
2929
var cache = Object.create(null);
3030

31-
return function(filepath, response, transform, content) {
31+
return function(filepath, response, transform, content, doNotCache) {
3232
var responseData;
3333

3434
if (directory) {
@@ -40,7 +40,7 @@ var createServeFile = function(fs, directory) {
4040
}
4141

4242
// serve from cache
43-
if (content) {
43+
if (content && !doNotCache) {
4444
response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain'));
4545

4646
// call custom transform fn to transform the data
@@ -57,7 +57,9 @@ var createServeFile = function(fs, directory) {
5757
return serve404(response, filepath);
5858
}
5959

60-
cache[filepath] = data.toString();
60+
if (!doNotCache) {
61+
cache[filepath] = data.toString();
62+
}
6163

6264
response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain'));
6365

lib/middleware/source_files.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ var createSourceFilesMiddleware = function(filesPromise, serveFile,
4646
// without timestamps - no cache (debug)
4747
common.setNoCacheHeaders(response);
4848
}
49-
}, file.content);
49+
}, file.content, file.doNotCache);
5050
} else {
5151
next();
5252
}

test/unit/file_list.spec.coffee

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,20 @@ describe 'file_list', ->
241241
expect(pathsFrom files.served).to.deep.equal ['/a.txt']
242242
done()
243243

244+
it 'should properly mark files that should not be cached', (done) ->
245+
# /a.* => /a.txt [nocache FALSE]
246+
# /some/*.js => /some/a.js, /some/b.js [nocache TRUE]
247+
files = [new config.Pattern('/a.*'), new config.Pattern('/some/*.js', true, true, true, true)]
248+
list = new m.List files, [], emitter, preprocessMock
249+
250+
refreshListAndThen (files) ->
251+
expect(pathsFrom files.served).to.deep.equal ['/a.txt', '/some/a.js', '/some/b.js']
252+
expect(preprocessMock.callCount).to.equal 1
253+
expect(files.served[0].doNotCache).to.be.false
254+
expect(files.served[1].doNotCache).to.be.true
255+
expect(files.served[2].doNotCache).to.be.true
256+
done()
257+
244258

245259
#============================================================================
246260
# List.getIncludedFiles()

test/unit/middleware/source_files.spec.coffee

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,19 @@ describe 'middleware.source_files', ->
174174
done()
175175

176176
callHandlerWith '/absolute/some/file.js'
177+
178+
it 'should not use cached content if doNotCache is set', (done) ->
179+
cachedFile = new File('/src/some.js')
180+
cachedFile.content = 'cached-content'
181+
cachedFile.doNotCache = true
182+
183+
servedFiles [
184+
cachedFile
185+
]
186+
187+
response.once 'end', ->
188+
expect(nextSpy).not.to.have.been.called
189+
expect(response).to.beServedAs 200, 'js-source'
190+
done()
191+
192+
callHandlerWith '/absolute/src/some.js'

0 commit comments

Comments
 (0)