Skip to content

Commit f49e5bd

Browse files
authored
Merge pull request #8 from Realytics/fix/stats-error-on-remove
Fix/stats error on remove
2 parents 7c64f03 + bd01eba commit f49e5bd

File tree

7 files changed

+84
-45
lines changed

7 files changed

+84
-45
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## v0.1.4
2+
* Fix send to closed channel case
3+
* Fix removed files case
4+
* Add `fork-ts-checker-service-start-error` hook
5+
6+
## v0.1.3
7+
* Fix "Cannot read property 'mtime' of undefined on OSX"
8+
9+
## v0.1.2
10+
* Workers mode works correctly (fixed typo)
11+
12+
## v0.1.1
13+
* Support memory limit in multi-process mode
14+
* Handle already closed channel case on sending ipc message
15+
16+
## v0.1.0
17+
* Initial release - not production ready.

README.md

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
[![Npm version](https://img.shields.io/npm/v/fork-ts-checker-webpack-plugin.svg?style=flat-square)](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin)
33
[![Build Status](https://travis-ci.org/Realytics/fork-ts-checker-webpack-plugin.svg?branch=master)](https://travis-ci.org/realytics/fork-ts-checker-webpack-plugin)
44

5-
Webpack plugin that runs typescript type checker (with optional linter) on separate processes.
5+
Webpack plugin that runs typescript type checker on a separate process.
66

77
## Installation ##
88
This plugin requires minimum **webpack 2**, **typescript 2.1** and optionally **tslint 5.0**
99
```sh
10-
npm install --save fork-ts-checker-webpack-plugin
10+
npm install --save-dev fork-ts-checker-webpack-plugin
1111
```
1212
Basic webpack config (with [ts-loader](https://github.com/TypeStrong/ts-loader))
1313
```js
@@ -43,18 +43,17 @@ var webpackConfig = {
4343

4444
## Motivation ##
4545
There is already similar solution - [awesome-typescript-loader](https://github.com/s-panferov/awesome-typescript-loader). You can
46-
add `CheckerPlugin` and delegate checker to the separate process. The problem with `awesome-typescript-loader` is that it's a lot slower
47-
than [ts-loader](https://github.com/TypeStrong/ts-loader) on incremental build in our case (~20s vs ~3s).
48-
Secondly, we use [tslint](https://palantir.github.io/tslint/) and we wanted to run this also on separate process.
49-
This is why we've created this plugin. The performance is great because of reusing Abstract Syntax Trees between compilations and sharing
50-
these trees with tslint. We can also scale checker with multi-process mode - it will split work between processes to utilize maximum cpu
51-
power.
46+
add `CheckerPlugin` and delegate checker to the separate process. The problem with `awesome-typescript-loader` was that, in our case,
47+
it was a lot slower than [ts-loader](https://github.com/TypeStrong/ts-loader) on an incremental build (~20s vs ~3s).
48+
Secondly, we use [tslint](https://palantir.github.io/tslint/) and we wanted to run this, along with type checker, in a separate process.
49+
This is why we've created this plugin. To provide better performance, plugin reuses Abstract Syntax Trees between compilations and shares
50+
these trees with tslint. It can be scaled with a multi-process mode to utilize maximum CPU power.
5251

5352
## Options ##
5453
**tsconfig** `string` - Path to tsconfig.json file. If not set, plugin will use `path.resolve(compiler.options.context, './tsconfig.json')`.
5554

5655
**tslint** `string | false` - Path to tslint.json file. If not set, plugin will use `path.resolve(compiler.options.context, './tslint.json')`.
57-
If `false`, disables tslint.
56+
If `false`, disables tslint.
5857

5958
**watch** `string | string[]` - Directories or files to watch by service. Not necessary but improves performance
6059
(reduces number of `fs.stat` calls).
@@ -72,18 +71,17 @@ power.
7271

7372
**silent** `boolean` - If `true`, logger will not be used. Default: `false`.
7473

75-
**workers** `number` - You can split type checking to few workers to speed-up on increment build.
76-
**Be careful** - if you don't want to increase build time, you should keep 1 core for *build* and 1 core for
77-
*system* free *(for example system with 4 cpu threads should use max 2 workers)*.
78-
Second thing - node doesn't share memory between workers so keep in mind that memory usage will increase
79-
linearly. If you want to use workers, please experiment with workers number. In some scenarios increasing this number
80-
**can increase check time** (and of course memory consumption).
74+
**workers** `number` - You can split type checking to a few workers to speed-up increment build.
75+
**Be careful** - if you don't want to increase build time, you should keep free 1 core for *build* and 1 core for
76+
a *system* *(for example system with 4 CPUs should use max 2 workers)*.
77+
Second thing - node doesn't share memory between workers - keep in mind that memory usage will increase.
78+
Be aware that in some scenarios increasing workers number **can increase checking time**.
8179
Default: `ForkTsCheckerWebpackPlugin.ONE_CPU`.
8280

8381
Pre-computed consts:
84-
* `ForkTsCheckerWebpackPlugin.ONE_CPU` - always use one cpu (core)
85-
* `ForkTsCheckerWebpackPlugin.ONE_CPU_FREE` - leave only one cpu for build (probably will increase build time)
86-
* `ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE` - leave two cpus free (one for build, one for system)
82+
* `ForkTsCheckerWebpackPlugin.ONE_CPU` - always use one CPU
83+
* `ForkTsCheckerWebpackPlugin.ONE_CPU_FREE` - leave only one CPU for build (probably will increase build time)
84+
* `ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE` - leave two CPUs free (one for build, one for system)
8785

8886
**memoryLimit** `number` - Memory limit for service process in MB. If service exits with allocation failed error, increase this number.
8987
Default: `2048`.
@@ -96,6 +94,7 @@ This plugin provides some custom webpack hooks (all are sync):
9694
|`fork-ts-checker-cancel`| Cancellation has been requested | `cancellationToken` |
9795
|`fork-ts-checker-waiting`| Waiting for results | `hasTsLint` |
9896
|`fork-ts-checker-service-start`| Service will be started | `tsconfigPath`, `tslintPath`, `watchPaths`, `workersNumber`, `memoryLimit` |
97+
|`fork-ts-checker-service-start-error` | Cannot start service | `error` |
9998
|`fork-ts-checker-service-out-of-memory`| Service is out of memory | - |
10099
|`fork-ts-checker-receive`| Plugin receives diagnostics and lints from service | `diagnostics`, `lints` |
101100
|`fork-ts-checker-emit`| Service will add errors and warnings to webpack compilation (`blockEmit: true`) | `diagnostics`, `lints`, `elapsed` |

lib/IncrementalChecker.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ IncrementalChecker.createProgram = function (programConfig, files, watcher, oldP
4747
host.getSourceFile = function (filePath, languageVersion, onError) {
4848
// first check if watcher is watching file - if not - check it's mtime
4949
if (!watcher.isWatchingFile(filePath)) {
50-
var stats = fs.statSync(filePath);
51-
52-
files.setMtime(filePath, stats.mtime.valueOf());
50+
try {
51+
var stats = fs.statSync(filePath);
52+
53+
files.setMtime(filePath, stats.mtime.valueOf());
54+
} catch (e) {
55+
// probably file does not exists
56+
files.remove(filePath);
57+
}
5358
}
5459

5560
// get source file only if there is no source in files register
@@ -145,7 +150,14 @@ IncrementalChecker.prototype.getLints = function (cancellationToken) {
145150
workSet.forEach(function (fileName) {
146151
cancellationToken.throwIfCancellationRequested();
147152

148-
this.linter.lint(fileName, undefined, this.linterConfig);
153+
try {
154+
this.linter.lint(fileName, undefined, this.linterConfig);
155+
} catch (e) {
156+
if (fs.existsSync(fileName)) {
157+
// it's not because file doesn't exist - throw error
158+
throw e;
159+
}
160+
}
149161
}.bind(this));
150162

151163
// set lints in files register

lib/cluster.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ var result = new WorkResult(pids);
2929
process.on('message', function (message) {
3030
// broadcast message to all workers
3131
workers.forEach(function (worker) {
32-
worker.send(message);
32+
try {
33+
worker.send(message);
34+
} catch (e) {
35+
// channel closed - something went wrong - close cluster...
36+
process.exit();
37+
}
3338
});
3439

3540
// clear previous result set

lib/index.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,16 @@ ForkTsCheckerWebpackPlugin.prototype.pluginCompile = function () {
156156
if (!this.service || !this.service.connected) {
157157
this.spawnService();
158158
}
159-
this.service.send(this.cancellationToken);
159+
160+
try {
161+
this.service.send(this.cancellationToken);
162+
} catch (error) {
163+
if (!this.options.silent && this.logger) {
164+
this.logger.error(this.colors.red('Cannot start checker service: ' + (error ? error.toString() : 'Unknown error')));
165+
}
166+
167+
this.compiler.applyPlugins('fork-ts-checker-service-start-error', error);
168+
}
160169
}.bind(this));
161170
};
162171

@@ -234,7 +243,7 @@ ForkTsCheckerWebpackPlugin.prototype.spawnService = function () {
234243
}
235244
if (this.tslint && !this.options.tslint) {
236245
// auto-detect tslint path - print to the user to be sure that it's proper file
237-
lines.push(this.colors.grey(this.tslint));
246+
lines.push(this.colors.grey(this.tslintPath));
238247
}
239248

240249
this.logger.info(lines.join('\n'));

package.json

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fork-ts-checker-webpack-plugin",
3-
"version": "0.1.3",
3+
"version": "0.1.4",
44
"description": "Runs typescript type checker and linter on separate process.",
55
"main": "lib/index.js",
66
"scripts": {
@@ -34,11 +34,11 @@
3434
"chai": "^3.5.0",
3535
"eslint": "^3.19.0",
3636
"istanbul": "^0.4.5",
37-
"mocha": "^3.2.0",
38-
"mock-fs": "^4.2.0",
37+
"mocha": "^3.4.1",
38+
"mock-fs": "^4.3.0",
3939
"mock-require": "^2.0.2",
4040
"rimraf": "^2.5.4",
41-
"sinon": "^2.1.0",
41+
"sinon": "^2.2.0",
4242
"typescript": "^2.1.0"
4343
},
4444
"peerDependencies": {
@@ -47,12 +47,9 @@
4747
},
4848
"dependencies": {
4949
"chalk": "^1.1.3",
50-
"chokidar": "^1.6.1",
50+
"chokidar": "^1.7.0",
5151
"lodash.endswith": "^4.2.1",
5252
"lodash.isstring": "^4.0.1",
5353
"lodash.startswith": "^4.2.1"
54-
},
55-
"optionalDependencies": {
56-
"tslint": "^5.0.0"
5754
}
5855
}

yarn.lock

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
249249
strip-ansi "^3.0.0"
250250
supports-color "^2.0.0"
251251

252-
chokidar@^1.6.1:
253-
version "1.6.1"
254-
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
252+
chokidar@^1.7.0:
253+
version "1.7.0"
254+
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
255255
dependencies:
256256
anymatch "^1.3.0"
257257
async-each "^1.0.0"
@@ -1232,9 +1232,9 @@ [email protected], [email protected], "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1:
12321232
dependencies:
12331233
minimist "0.0.8"
12341234

1235-
mocha@^3.2.0:
1236-
version "3.3.0"
1237-
resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.3.0.tgz#d29b7428d3f52c82e2e65df1ecb7064e1aabbfb5"
1235+
mocha@^3.4.1:
1236+
version "3.4.1"
1237+
resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.4.1.tgz#a3802b4aa381934cacb38de70cf771621da8f9af"
12381238
dependencies:
12391239
browser-stdout "1.3.0"
12401240
commander "2.9.0"
@@ -1248,9 +1248,9 @@ mocha@^3.2.0:
12481248
mkdirp "0.5.1"
12491249
supports-color "3.1.2"
12501250

1251-
mock-fs@^4.2.0:
1252-
version "4.2.0"
1253-
resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.2.0.tgz#ef53ae17b77e64f67816dd0467f29208a3b26e19"
1251+
mock-fs@^4.3.0:
1252+
version "4.3.0"
1253+
resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.3.0.tgz#c2fab8d784283287e9b6ae7538f2dc56c1a05ed7"
12541254

12551255
mock-require@^2.0.2:
12561256
version "2.0.2"
@@ -1638,9 +1638,9 @@ signal-exit@^3.0.0:
16381638
version "3.0.2"
16391639
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
16401640

1641-
sinon@^2.1.0:
1642-
version "2.1.0"
1643-
resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.1.0.tgz#e057a9d2bf1b32f5d6dd62628ca9ee3961b0cafb"
1641+
sinon@^2.2.0:
1642+
version "2.2.0"
1643+
resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.2.0.tgz#3b1b42ff5defcbf51a52a62aca6d61171b9fd262"
16441644
dependencies:
16451645
diff "^3.1.0"
16461646
formatio "1.2.0"

0 commit comments

Comments
 (0)