Skip to content

Commit cb0c75a

Browse files
author
Piotr Oleś
committed
Improvements
1 parent 38c2015 commit cb0c75a

16 files changed

+644
-1290
lines changed

README.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,42 @@ var webpackConfig = {
4848
TODO
4949

5050
## Options ##
51-
| option | type | description |
52-
|--------|------|-------------|
53-
|**tsconfig**| `string` | Path to tsconfig.json file. If not set, plugin will use `path.resolve(compiler.context, './tsconfig.json')`. |
54-
|**tslint**| `string` or `false` | Path to tslint.json file. If not set, plugin will use `path.resolve(compiler.context, './tslint.json')`. If `false`, disables tslint.|
55-
|**watch**| `string` or `string[]` | Files or directories to watch be service. Not necessary but improves performance (reduces number of `fs.stat` calls). |
56-
|**blockEmit**| `boolean` | If `true`, plugin will block emit until check will be done. It's good setting for ci/production build because webpack will return code != 0 if there are type/lint errors. Default: `false`. |
57-
|**ignoreDiagnostics**| `number[]` | List of typescript diagnostic codes to ignore. |
58-
|**ignoreLints**| `string[]` | List of tslint rule names to ignore. |
59-
|**colors**| `boolean` | If `false`, disables colors for logger. Default: `true`. |
60-
|**logger**| `LoggerInterface` | Logger instance. It should be object that implements method: `error`, `warn`, `info`. Default: `console`.|
61-
|**silent**| `boolean` | If `true`, logger will not be used. Default: `false`.|
62-
|**cluster**| `number` | You can split type checking to few workers to speed-up on increment build. But remember: if you don't want type checker to affect build time, you should keep 1 core for build and 1 core for system. Also - node doesn't share memory so keep in mind that memory usage will increase linear. Default: `1`.|
51+
**tsconfig** `string` - Path to tsconfig.json file. If not set, plugin will use `path.resolve(compiler.options.context, './tsconfig.json')`.
52+
53+
**tslint** `string | false` - Path to tslint.json file. If not set, plugin will use `path.resolve(compiler.options.context, './tslint.json')`.
54+
If `false`, disables tslint.
55+
56+
**watch** `string | string[]` - Directories or files to watch by service. Not necessary but improves performance
57+
(reduces number of `fs.stat` calls).
58+
59+
**blockEmit** `boolean` - If `true`, plugin will block emit until check will be done. It's good setting for ci/production build because
60+
webpack will return code != 0 if there are type/lint errors. Default: `false`.
61+
62+
**ignoreDiagnostics** `number[]` - List of typescript diagnostic codes to ignore.
63+
64+
**ignoreLints** `string[]` - List of tslint rule names to ignore.
65+
66+
**colors** `boolean` - If `false`, disables built-in colors in logger messages. Default: `true`.
67+
68+
**logger** `object` - Logger instance. It should be object that implements method: `error`, `warn`, `info`. Default: `console`.
69+
70+
**silent** `boolean` - If `true`, logger will not be used. Default: `false`.
71+
72+
**workers** `number` - You can split type checking to few workers to speed-up on increment build.
73+
**Be careful** - if you don't want to increase build time, you should keep 1 core for *build* and 1 core for
74+
*system* free *(for example system with 4 cpu threads should use max 2 workers)*.
75+
Second thing - node doesn't share memory between workers so keep in mind that memory usage will increase
76+
linearly. If you want to use workers, please experiment with workers number. In some scenarios increasing this number
77+
**can increase check time** (and of course memory consumption).
78+
Default: `ForkTsCheckerWebpackPlugin.ONE_CPU`.
79+
80+
Pre-computed consts:
81+
* `ForkTsCheckerWebpackPlugin.ONE_CPU` - always use one cpu (core)
82+
* `ForkTsCheckerWebpackPlugin.ONE_FREE_CPU` - leave only one cpu for build (probably will increase build time)
83+
* `ForkTsCheckerWebpackPlugin.TWO_FREE_CPUS` - leave two cpus free (one for build, one for system)
84+
85+
**memoryLimit** `number` - Memory limit for service process in MB. If service exits with allocation failed error, increase this number.
86+
Default: `2048`.
6387

6488
## License ##
6589
MIT

karma.conf.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

lib/CancellationToken.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ CancellationToken.prototype.toJSON = function () {
2525
};
2626
};
2727

28+
CancellationToken.prototype.getCancellationFilePath = function () {
29+
return path.join(os.tmpdir(), this.cancellationFileName);
30+
};
31+
2832
CancellationToken.prototype.isCancellationRequested = function () {
2933
if (this.isCancelled) {
3034
return true;
@@ -36,7 +40,7 @@ CancellationToken.prototype.isCancellationRequested = function () {
3640
if (duration > 10) {
3741
// check no more than once every 10ms
3842
this.lastCancellationCheckTime = time;
39-
this.isCancelled = fs.existsSync(getCancellationFilePath(this.cancellationFileName));
43+
this.isCancelled = fs.existsSync(this.getCancellationFilePath());
4044
}
4145

4246
return this.isCancelled;
@@ -49,15 +53,13 @@ CancellationToken.prototype.throwIfCancellationRequested = function () {
4953
};
5054

5155
CancellationToken.prototype.requestCancellation = function () {
52-
fs.writeFileSync(getCancellationFilePath(this.cancellationFileName), '');
56+
fs.writeFileSync(this.getCancellationFilePath(), '');
57+
this.isCancelled = true;
5358
};
5459

5560
CancellationToken.prototype.cleanupCancellation = function () {
56-
if (this.isCancelled) {
57-
fs.unlink(getCancellationFilePath(this.cancellationFileName));
61+
if (this.isCancelled && fs.existsSync(this.getCancellationFilePath())) {
62+
fs.unlinkSync(this.getCancellationFilePath());
63+
this.isCancelled = false;
5864
}
5965
};
60-
61-
function getCancellationFilePath (cancellationFileName) {
62-
return path.join(os.tmpdir(), cancellationFileName);
63-
}

lib/FilesRegister.js

Lines changed: 34 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,65 @@
11

2-
function FilesRegister () {
3-
this.register = {};
2+
function FilesRegister (dataFactory) {
3+
this.files = {};
4+
this.dataFactory = dataFactory;
45
}
56
module.exports = FilesRegister;
67

7-
FilesRegister.prototype.forEach = function (callback) {
8-
Object.keys(this.register).forEach(function (key) {
9-
callback(key, this.register[key]);
10-
}.bind(this));
8+
FilesRegister.prototype.keys = function () {
9+
return Object.keys(this.files);
1110
};
1211

13-
FilesRegister.prototype.keys = function() {
14-
return Object.keys(this.register);
15-
};
16-
17-
FilesRegister.prototype.addFile = function (fileName) {
18-
this.register[fileName] = {
12+
FilesRegister.prototype.add = function (filePath) {
13+
this.files[filePath] = {
1914
mtime: undefined,
20-
source: undefined,
21-
linted: false,
22-
lints: []
15+
data: this.dataFactory(undefined)
2316
};
2417
};
2518

26-
FilesRegister.prototype.removeFile = function (fileName) {
27-
if (this.hasFile(fileName)) {
28-
delete this.register[fileName];
19+
FilesRegister.prototype.remove = function (filePath) {
20+
if (this.has(filePath)) {
21+
delete this.files[filePath];
2922
}
3023
};
3124

32-
FilesRegister.prototype.hasFile = function (fileName) {
33-
return this.register.hasOwnProperty(fileName);
25+
FilesRegister.prototype.has = function (filePath) {
26+
return this.files.hasOwnProperty(filePath);
3427
};
3528

36-
FilesRegister.prototype.getFile = function (fileName) {
37-
if (!this.hasFile(fileName)) {
38-
throw new Error('File "' + fileName + '" not found in register.');
29+
FilesRegister.prototype.get = function (filePath) {
30+
if (!this.has(filePath)) {
31+
throw new Error('File "' + filePath + '" not found in register.');
3932
}
4033

41-
return this.register[fileName];
34+
return this.files[filePath];
4235
};
4336

44-
FilesRegister.prototype.ensureFile = function (fileName) {
45-
if (!this.hasFile(fileName)) {
46-
this.addFile(fileName);
37+
FilesRegister.prototype.ensure = function (filePath) {
38+
if (!this.has(filePath)) {
39+
this.add(filePath);
4740
}
4841
};
4942

50-
FilesRegister.prototype.setSource = function (fileName, source) {
51-
this.ensureFile(fileName);
52-
53-
this.register[fileName].source = source;
54-
};
55-
56-
FilesRegister.prototype.hasSource = function (fileName) {
57-
return this.hasFile(fileName) && !!this.getFile(fileName).source;
43+
FilesRegister.prototype.getData = function (filePath) {
44+
return this.get(filePath).data;
5845
};
5946

60-
FilesRegister.prototype.getSource = function (fileName) {
61-
if (!this.hasSource(fileName)) {
62-
throw new Error('Cannot get source of "' + fileName + '" file.');
63-
}
47+
FilesRegister.prototype.mutateData = function (filePath, mutator) {
48+
this.ensure(filePath);
6449

65-
return this.getFile(fileName).source;
50+
mutator(this.files[filePath].data);
6651
};
6752

68-
FilesRegister.prototype.setMtime = function (fileName, mtime) {
69-
this.ensureFile(fileName);
70-
71-
if (this.register[fileName].mtime !== mtime) {
72-
this.register[fileName].linted = false;
73-
this.register[fileName].lints = [];
74-
this.register[fileName].mtime = mtime;
75-
76-
// file has been changed - we are not sure about it's current source
77-
this.register[fileName].source = undefined;
78-
}
53+
FilesRegister.prototype.getMtime = function (filePath) {
54+
return this.get(filePath).mtime;
7955
};
8056

81-
FilesRegister.prototype.getLints = function () {
82-
var lints = [];
83-
84-
this.forEach(function (fileName, fileEntry) {
85-
lints.push.apply(lints, fileEntry.lints);
86-
});
57+
FilesRegister.prototype.setMtime = function (filePath, mtime) {
58+
this.ensure(filePath);
8759

88-
return lints;
89-
};
90-
91-
FilesRegister.prototype.consumeLint = function (lint) {
92-
var fileName = lint.getFileName();
93-
94-
this.ensureFile(fileName);
95-
96-
this.register[fileName].linted = true;
97-
this.register[fileName].lints.push(lint);
98-
};
99-
100-
FilesRegister.prototype.consumeLints = function (lints) {
101-
lints.forEach(function (lint) {
102-
this.consumeLint(lint);
103-
}.bind(this));
104-
};
105-
106-
FilesRegister.prototype.setAllLinted = function () {
107-
this.keys().forEach(function (fileName) {
108-
this.register[fileName].linted = true;
109-
}.bind(this))
60+
if (this.files[filePath].mtime !== mtime) {
61+
this.files[filePath].mtime = mtime;
62+
// file has been changed - we have to reset data
63+
this.files[filePath].data = this.dataFactory(this.files[filePath].data);
64+
}
11065
};

lib/FilesWatcher.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ function FilesWatcher (watchPaths, watchExtensions) {
66
this.watchPaths = watchPaths;
77
this.watchExtensions = watchExtensions;
88
this.watchers = [];
9-
this.changeListeners = [];
10-
this.unlinkListeners = [];
9+
this.listeners = {};
1110
}
1211
module.exports = FilesWatcher;
1312

@@ -16,21 +15,25 @@ FilesWatcher.prototype.isFileSupported = function (filePath) {
1615
};
1716

1817
FilesWatcher.prototype.watch = function () {
18+
if (this.isWatching()) {
19+
throw new Error('Cannot watch again - already watching.');
20+
}
21+
1922
this.watchers = this.watchPaths.map(function (watchPath) {
2023
return chokidar.watch(
2124
watchPath,
2225
{ persistent: true }
2326
)
2427
.on('change', function (filePath, stats) {
2528
if (this.isFileSupported(filePath)) {
26-
this.changeListeners.forEach(function (changeListener) {
29+
(this.listeners['change'] || []).forEach(function (changeListener) {
2730
changeListener(filePath, stats);
2831
});
2932
}
3033
}.bind(this))
3134
.on('unlink', function (filePath) {
3235
if (this.isFileSupported(filePath)) {
33-
this.unlinkListeners.forEach(function (unlinkListener) {
36+
(this.listeners['unlink'] || []).forEach(function (unlinkListener) {
3437
unlinkListener(filePath);
3538
});
3639
}
@@ -41,6 +44,7 @@ FilesWatcher.prototype.watch = function () {
4144
FilesWatcher.prototype.isWatchingFile = function (filePath) {
4245
return (
4346
this.isWatching() &&
47+
this.isFileSupported(filePath) &&
4448
this.watchPaths.some(function (watchPath) {
4549
return startsWith(filePath, watchPath);
4650
})
@@ -51,22 +55,18 @@ FilesWatcher.prototype.isWatching = function () {
5155
return this.watchers.length > 0;
5256
};
5357

54-
FilesWatcher.prototype.onChange = function (changeListener) {
55-
this.changeListeners.push(changeListener);
58+
FilesWatcher.prototype.on = function (event, listener) {
59+
if (!this.listeners[event]) {
60+
this.listeners[event] = [];
61+
}
5662

57-
return function unsubscribe () {
58-
this.changeListeners.filter(function (listener) {
59-
return listener !== changeListener;
60-
});
61-
}.bind(this);
63+
this.listeners[event].push(listener);
6264
};
6365

64-
FilesWatcher.prototype.onUnlink = function (unlinkListener) {
65-
this.unlinkListeners.push(unlinkListener);
66-
67-
return function unsubscribe () {
68-
this.unlinkListeners.filter(function (listener) {
69-
return listener !== unlinkListener;
66+
FilesWatcher.prototype.off = function (event, listener) {
67+
if (this.listeners[event]) {
68+
this.listeners[event] = this.listeners[event].filter(function (oldListener) {
69+
return oldListener !== listener;
7070
});
71-
}.bind(this);
71+
}
7272
};

0 commit comments

Comments
 (0)