-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: --onEmit #167
feat: --onEmit #167
Conversation
We needed this to avoid an infinite loop, maybe it will be useful for others. Problem --- If the `onSuccess` COMMAND touches any source file (e.g. generate GraphQL types), then there will be an infinite loop. Solution --- TypeScript does not emit for unchanged source files, so `onEmit` will not infinite loop. It also has added benefits: - less noisy on success - if `tsconfig.json` is configured to emit on error, user's app will still update with type errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand your solution, can you please provide more information?
and thanks for the PR!
case 'run-on-emit-command': | ||
if (emitKiller) { | ||
emitKiller().then(runOnEmitCommand); | ||
} | ||
break; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are missing the client.ts
part. and also missing tests
OK, I've simplified and documented the solution, added tests, and also improved the PR description. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update!
I'm sorry that I'm picky, but this is complicated as it is, so I want the code to be as clear as possible.
README.md
Outdated
@@ -11,6 +11,8 @@ | |||
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | |||
| `--onSuccess COMMAND` | Executes `COMMAND` on **every successful** compilation. | | |||
| `--onFirstSuccess COMMAND` | Executes `COMMAND` on the **first successful** compilation. | | |||
| `--onEmit COMMAND` | Executes debounced `COMMAND` on **every emitted file**. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on every emitted file? are you sure?
Does this means that if I have a complication of 100 files, this command will run 100 times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe provide a use case for when someone will want to use onEmit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this means that if I have a complication of 100 files, this command will run 100 times?
No because of --onEmitDebounce
. Just added a note in the README for this.
Also, maybe provide a use case for when someone will want to use onEmit?
Just added more to this line
@@ -71,6 +75,27 @@ function killProcesses(currentCompilationId: number, killAll: boolean): Promise< | |||
return runningKillProcessesPromise; | |||
} | |||
|
|||
let runningKillEmitProcessesPromise: Promise<number> | null = null; | |||
function killEmitProcesses(currentEmitId: number): Promise<number> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that I understand this function... can you please explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just added a comment to the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last small changes
Co-authored-by: Gil Amran <gilamran@gmail.com>
Co-authored-by: Gil Amran <gilamran@gmail.com>
Co-authored-by: Gil Amran <gilamran@gmail.com>
Co-authored-by: Gil Amran <gilamran@gmail.com>
thanks for the suggestions, updated |
Published on version 6.1.0 |
Thanks @gilamran ! It looks like the npm version doesn't have the JS changes: https://www.npmjs.com/package/tsc-watch?activeTab=code Maybe it needs: - "prepublish": "crlf --set=LF index.js client.js dist/**/*",
+ "prepublishOnly": "npm run build && crlf --set=LF index.js client.js dist/**/*", |
Problem
In case 1, it may be a waste to run the COMMAND, and the worst case it can cause an infinite loop. Example: app starts -> generates introspected GraphQL types -> triggers tsc -> app restarts -> ... -> triggers tsc -> no emit because unchanged -> app still restarts again due to onSuccess.
In case 2, we may still want to run the COMMAND. In fact, it is because this is such a popular behavior that
noEmitOnError
is defaulted to false:Solution
Add a
--noEmit
option, which may better serve use-cases such as restarting an app/server. Since TypeScript does not debounce emits, we also need to debounce ourselves with a--noEmitDebounceMs
option (default 300ms).