The plugin crashed right after rebuilding (in watch mode), with below message
/~/node_modules/fork-ts-checker-webpack-plugin/lib/index.js:323
var elapsed = Math.round(_this.elapsed[0] * 1E9 + _this.elapsed[1]);
^
TypeError: Cannot read property '0' of undefined
at ForkTsCheckerWebpackPlugin.doneCallback (~node_modules/fork-ts-checker-webpack-plugin/lib/index.js:323:51)
at ForkTsCheckerWebpackPlugin.handleServiceMessage (/~/node_modules/fork-ts-checker-webpack-plugin/lib/index.js:273:52)
at ChildProcess.<anonymous> (/Users/rok/GitHub/sinicompany/closer-www/node_modules/fork-ts-checker-webpack-plugin/lib/index.js:231:70)
at emitTwo (events.js:126:13)
at ChildProcess.emit (events.js:214:7)
at emit (internal/child_process.js:772:12)
at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)
webpack 3.8.1
webpack-dev-server 2.9.4
fork-ts-checker-plugin 0.2.9
typescirpt 2.6.1
tslint 5.8.0
tslint-microsoft-contrib 5.0.1
fork-ts-checker-plugin
{
"tsconfig": "../tsconfig.json",
"tslint": "../tslint.json",
"checkSyntacticErrors": true,
}
tsconfig
{
"compilerOptions": {
"sourceMap": true,
"target": "es5",
"jsx": "react",
"module": "esnext",
"moduleResolution": "node",
"allowJs": false,
"importHelpers": true,
"emitDecoratorMetadata": false,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"downlevelIteration": true,
"pretty": true,
"declaration": false,
"noUnusedLocals": true,
"noUnusedParameters": false,
"noImplicitAny": false,
"noImplicitReturns": false,
"removeComments": false,
"strictNullChecks": false,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": ["src/*", "*"]
},
"lib": [
"es6",
"es7",
"dom"
]
},
"exclude": [
"dist",
"node_modules"
]
}
tslint
{
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib"
],
...
}
it works well with [email protected].
Can you provide a minimal reproduction repo please?
I'm getting this error, too. Although my error message isn't as nice and I had to use the Chrome inspector to find the problem. I only see this bug when I use the watch option for WebPack set to true. If I set it to false, everything works perfectly.
@rokoroku Is that the case for you?
I might be willing to see if I can create a minimal reproduction if you can't duplicate this @johnnyreilly. Is there some basic project I can piggy-back off of so I don't have to create a separate setup just for this?
Hey @c1moore,
Thanks for that - this is probably a good basis for a minimal repro: https://github.com/TypeStrong/ts-loader/tree/master/examples/fork-ts-checker
@johnnyreilly I can only reproduce this when using this plugin in conjunction with Grunt. I'm not sure if @rokoroku has the same setup.
You can see how I reproduced it here. My changes were extremely simple:
watch: true to the webpack config filegrunt-webpackgrunt runSeems odd that grunt would be what affects _this.elapsed...
It does - the issue appears to happen in the done callback here: https://github.com/Realytics/fork-ts-checker-webpack-plugin/blob/master/src/index.ts#L465
@piotr-oles can you think why grunt wouldn't play nice with fork-ts-checker-webpack-plugin? I had 1 idea. The plugin looks like it has some global variables in the form of node's process.env.:
env: Object.assign(
{},
process.env,
{
TSCONFIG: this.tsconfigPath,
TSLINT: this.tslintPath || '',
WATCH: this.isWatching ? this.watchPaths.join('|') : '',
WORK_DIVISION: Math.max(1, this.workersNumber),
MEMORY_LIMIT: this.memoryLimit,
CHECK_SYNTACTIC_ERRORS: this.checkSyntacticErrors
}
),
Perhaps these are colliding with similar Grunt variables? Does that make sense as a potential issue?
Essentially the problem seems to be that this code is not running: https://github.com/Realytics/fork-ts-checker-webpack-plugin/blob/master/src/index.ts#L379
this.elapsed = process.hrtime(this.started)
https://github.com/Realytics/fork-ts-checker-webpack-plugin/blob/master/src/index.ts#L313
Not sure why grunt would cause that though
@johnnyreilly I'm using the Chrome inspector to walk through some of the code. It looks like this.elapsed _is_ initially set. However, when createDoneCallback() is called, elapsed is not defined. In other words, handleServiceMessage() is called after createDoneCallback() and I believe after a child process is spun off. handleServiceMessage() does define elapsed on this, but _this in createDoneCallback() is never updated.
Presumably, createDoneCallback()'s _this and handleServiceMessage()'s this refer to different this objects. I wonder if that has anything to do with child-process. Perhaps handleServiceMessage() is being called in a child process and not modifying the same this?
However, this _does_ have elapsed defined within the done callback defined by createDoneCallback() (but not _this).
The solution I found was to use this instead of _this in the callback created by createDoneCallback().
Sorry for late, and thanks @c1moore for reproducing example.
In my case, I use gulp, not grunt. It seems like this issue is related to such build tools.
The solution I found was to use
thisinstead of_thisin the callback created bycreateDoneCallback().
That's absolute gold @c1moore - thanks for digging into it. Let me have a little play and report back
Okay I've made a propective fix; I haven't had time to test it properly but I'm fairly confident this should resolve the issue. My fix can be viewed here: https://github.com/johnnyreilly/fork-ts-checker-webpack-plugin
We're using https://github.com/typestrong/fork-ts-checker-webpack-plugin as an __@next__ channel for the plugin. I've get this pushed up there so you can have a test.
Can you advise if this resolves the issue? If so I'll look to submit a PR for @piotr-oles to review
@johnnyreilly It might be worth testing outside of the context of Grunt/Gulp, but I'll give it a try. I don't understand how I can get this update, though. Should I use your fork, pull directly from the typestrong repo, or do something like npm install fork-ts-checker-webpack-plugin@next? It sounds like I should use the typestrong repo.
That's absolute gold @c1moore - thanks for digging into it
I forgot I was messing around with the compiled version of the TypeScript you guys are looking at. Glad in helped, though.
Hey @c1moore
The typestrong repo contains the compiled code in a github repo that you can reference in your package.json.
Use the instructions in the readme here: https://github.com/typestrong/fork-ts-checker-webpack-plugin
It was me that ported the plugin to Typescript and my change reverts a change I made to do with the lexical binding of this. It's now more in line with the original is codebase
Did you get chance to test this @c1moore?
@johnnyreilly Sorry, I've been busy. That seems to work for me.
@johnnyreilly it seems work for me too. 馃憤
Great - I'll submit a PR. Thanks!
Merged - will be released as v0.2.10 :)
@piotr-oles I don't see v0.2.10 available on npmjs yet, but it seems to be available on GitHub. Is there some delay for the npm registry to update or are you holding off on releasing to npm for the time being? If the latter, is there an ETA for its release?
Hey @c1moore,
Hopefully should be out soon - see: https://github.com/Realytics/fork-ts-checker-webpack-plugin/issues/83
@c1moore v0.2.10 released :)
Yay!
Most helpful comment
@johnnyreilly I'm using the Chrome inspector to walk through some of the code. It looks like
this.elapsed_is_ initially set. However, whencreateDoneCallback()is called,elapsedis not defined. In other words,handleServiceMessage()is called aftercreateDoneCallback()and I believe after a child process is spun off.handleServiceMessage()does defineelapsedonthis, but_thisincreateDoneCallback()is never updated.Presumably,
createDoneCallback()'s_thisandhandleServiceMessage()'sthisrefer to differentthisobjects. I wonder if that has anything to do withchild-process. PerhapshandleServiceMessage()is being called in a child process and not modifying the samethis?However,
this_does_ haveelapseddefined within the done callback defined bycreateDoneCallback()(but not_this).The solution I found was to use
thisinstead of_thisin the callback created bycreateDoneCallback().