Giter Club home page Giter Club logo

tsc-watch's Introduction

Build Status

The nodemon for TypeScript

tsc-watch starts the installed TypeScript compiler (tsc) with --watch parameter, with the ability to react to compilation status. tsc-watch was created to allow an easy dev process with TypeScript. Commonly used to restart a node server, similar to nodemon but for TypeScript.

Anything that you can do with tsc you can do with tsc-watch, the only difference is that tsc-watch can react to compilation status.

Argument Description
--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, ignoring unchanged files and disregards compilation success or failure.
--onEmitDebounceMs DELAY Delay by which to debounce --onEmit (default: 300).
--onFailure COMMAND Executes COMMAND on every failed compilation.
--onCompilationStarted COMMAND Executes COMMAND on every compilation start event (initial and incremental).
--onCompilationComplete COMMAND Executes COMMAND on every successful or failed compilation.
--maxNodeMem Calls node with a specific memory limit max_old_space_size, to use if your project needs more memory.
--noColors By default tsc-watch adds colors the output with green
on success, and in red on failure.
Add this argument to prevent that.
--noClear In watch mode the tsc compiler clears the screen before reporting
Add this argument to prevent that.
--signalEmittedFiles Will run tsc compiler with --listEmittedFiles, but hiding TSFILE lines. Use it to enable file_emitted event, while keeping tsc stdout silent.
--silent Do not print any messages on stdout.
--compiler PATH The PATH will be used instead of typescript compiler.
Default is typescript/bin/tsc

Notes:

  • That all the above COMMANDs will be killed on process exit. (Using SIGTERM)

  • A COMMAND is a single command and not multi command like script1.sh && script2.sh

  • Any child process (COMMAND) will be terminated before creating a new one.

Install

npm install tsc-watch --save-dev
## for command-line usage
npm install -g typescript tsc-watch

Usage

From Command-Line

## Watching a project (with tsconfig.json)
tsc-watch --onSuccess "node ./dist/server.js"

## Beep on failure
tsc-watch --onFailure "echo Beep! Compilation Failed"

## Watching a single file
tsc-watch server.ts --outDir ./dist --onSuccess "node ./dist/server.js"

## Custom compiler
tsc-watch --onSuccess "node ./dist/server.js" --compiler my-typescript/bin/tsc

From npm script

"dev-server": "tsc-watch --noClear -p ./src/tsconfig.json --onSuccess \"node ./dist/server.js\"",

From javascript

You can see a detailed example here

The client is implemented as an instance of Node.JS's EventEmitter, with the following events:

  • started - Emitted upon the compilation start (initial or incremental).
  • first_success - Emitted upon first successful compilation.
  • subsequent_success - Emitted upon every subsequent successful compilation.
  • compile_errors - Emitted upon every failing compilation.
  • file_emitted - Emitted upon every file transpiled if --listEmittedFiles is used.

Once subscribed to the relevant events, start the client by running watch.start()

To kill the client, run watch.kill()

Example usage:

// Using CommonJS:
const { TscWatchClient } = require('tsc-watch/client');
// Using ES6 import:
import { TscWatchClient } from 'tsc-watch/client';

const watch = new TscWatchClient();

watch.on('started', () => {
  console.log('Compilation started');
});

watch.on('first_success', () => {
  console.log('First success!');
});

watch.on('success', () => {
  // Your code goes here...
});

watch.on('compile_errors', () => {
  // Your code goes here...
});

watch.start('--project', '.');

try {
  // do something...
} catch (e) {
  watch.kill(); // Fatal error, kill the compiler instance.
}

Notes:

  • The (onSuccess) COMMAND will not run if the compilation failed.
  • The (onEmit) COMMAND will not run if the compilation succeeded with no changed files, unless it is the first success.
  • The (onEmit) COMMAND will run even if the compilation failed, but emitted changed files.
  • The (onEmit) COMMAND will not run 100 times for 100 files, due to --onEmitDebounce
  • The (onEmit) COMMAND is not cancelling the onSuccess/onFirstSuccess/onFailure/onCompilationComplete/onCompilationStarted commands and vice versa.
  • tsc-watch is using the currently installed TypeScript compiler.
  • tsc-watch is not changing the compiler, just adds the new arguments, compilation is the same, and all other arguments are the same.

tsc-watch's People

Contributors

alxwrd avatar animalupi avatar asapien avatar barkayal avatar boyanio avatar carnun avatar ddunkin avatar dependabot[bot] avatar dko-slapdash avatar fauxfaux avatar fmvilas avatar frank-orellana avatar galkin avatar gil-fireblocks avatar gilamran avatar hwwi avatar ibc avatar igrayson avatar jonaskello avatar llllvvuu avatar merceyz avatar pp0rtal avatar pronebird avatar roblav96 avatar sosoba avatar yardenshoham avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tsc-watch's Issues

Windows newline issue

I'm trying to use this module, but it's giving the error described here: ifrost/afterwriting-labs#69

My temporary work around is to run

dos2unix node_modules/tsc-watch/tsc-watch.js

As a permanent fix can you republish with core.autocrlf = false as described above?

Feature request: Support multiple tsconfig.json files

My application is a monorepo with multiple packages where each package have it's own tsconfig.json. I would like to restart my server on a change to any of the packages. So for example I want to to this:

tsc-watch -p ./packages/foo-server -p ./packages/foo-utils --onSuccess 'node ./packages/foo-server/lib/server.js' -

So the request is to support multiple instances of the -p. The regular tsc --watch only supports one instance.

onSuccess does not seem to handle two commands accordingly

I have yarn commands like so...

    "copy-dangling": "copyfiles -u 1 src/**/*.json src/**/*.pug src/**/*.sql dist/",
    "dev": "yarn clean-dist && tsc-watch --onSuccess \"yarn copy-dangling && node --require dotenv/config dist/index.js\"",

because the onSuccess is running multiple commands, it seems to incorrectly parse out the ampersands && and turns it into something like this:

copyfiles -u 1 src/**/*.json src/**/*.pug src/**/*.sql dist/ '&&' node --require dotenv/config dist/index.js

(notice the quotes around the ampersands)

does this ignores my tsconfig.json file?

Not sure but when I use regular tsc compare to tsc-watch it compiles differently.

Also I have these:

"noUnusedLocals": true,
"noUnusedParameters": true

When I run regular tsc it fails if it meets these rules but with tsc-watch it succeeds even with these rules which makes me assume that it's ignoring the tsconfig.json file

tsc-watch kills the spawned process on recompilation

Hi,

I run tsc-watch with the following command:

tsc-watch --sourceMap --onFirstSuccess "node run-my-app-that-does-hot-reload.js"

Changing any file kills the node process. How do you circumvent this?

Workaround: Used a programmatic API via tsc-watch/client to prevent the node process from being killed

Send signal on reload

Is there way to send signal into process when code has been updatet? Something like:

tsc-watch --onFirstSuccess "node ./dist/main.js" --onSuccess SIGINT

tsc-watch client fails

Client fails on unresolved path:
Error: Cannot find module '/Users/#USER/$PROJECT_ROOT/lib/tsc-watch.js'

Starting with 1.1.35, hangs after compilation but before onSuccess runs

running:
tsc-watch --onSuccess "./scripts/start:dev.sh" --onFailure "echo 'Beep! Compilation Failed'"

1.1.34

[3:40:54 PM] Starting compilation in watch mode...
[3:41:05 PM] Compilation complete. Watching for file changes.
+ ./scripts/db:migrate.sh
Local redis port 9089
+ migrate_cmd='node ./dist/src/migrate.js'
+ '[' -z '' ']'
...

1.1.35

[3:48:22 PM] Starting compilation in watch mode...
[3:48:32 PM] Compilation complete. Watching for file changes.

[hangs indefinitely, and server never starts]

OSX

Run server on both onSuccess and onFailure

When running the onFailure process the onSuccess run previously doesn't get closed and vice versa.

The use case is I want to always run same node server on either success or failure, and apparently, the process is not killed.

On Windows, running tsc-watch uses 50%-60% of CPU

When running tsc-watch, on my Windows machine, the CPU usage for the Node.js process alone spikes to 50%-60%. With the other apps that I have running on my laptop, it basically spikes the total CPU usage to 100%.

This is how tsc-watch is being invoked:

./node_modules/.bin/tsc-watch --onSuccess node build/server.js

Is it correct to assume that the constant checking for file changes is what is causing the CPU usage spike?

Is there a polling option to configure how often tsc-watch checks for changes, or other way to resolve this issue?

Thanks!

License

Hi, please add a compatible OSS license, thanks!

how to exclude folders ?

I am using tsc watch with nrest js application and i have a module which uploads a file. However when i upload a file, tsc watch restarts the nestjs application

handle sigterm

I suggest adding the following line to tsc-watch :

process.on('SIGTERM', () => tscProcess.kill(0));

tsconfig.json path

Hello,

Firstly, thanks for writing this package, it's been super useful!
I have a question, as it seems it's not been asked before, and I could not find anything about it in the docs:

Is it possible to set the path of the tsconfig.json ? For my build process needs I have to use a specific tsconfig.build.json and I was looking at how to use ts-watch with this file instead of the default.

I see there is compiler option, but no option to set a custom tsconfig file. (-p flag to it)
Would this be feasible ?

Cheers!

Upgrade `ps-tree` dependency due to npm dependency attack

dominictarr/event-stream#116

An attacker gained control of the event-stream repository and injected malicious code. This package must be upgraded to the latest version of ps-tree to remove the malicious code.

The latest version of this package installs flatmap-stream thanks to this dependency chain ps-tree 1.1.0 > event-stream 3.3.6 > flatmap-stream 0.1.1.

This attack was a targetted attack at anyone who was using the copay-dash package, and would attempt to steal your BTC or BCH wallet keys.

Option 'project' cannot be mixed with source files on a command line

I'm trying to use tsc-watch to compile a specific subdirectory with its own tsconfig.json and then run a compiled file in node but I'm getting that error.

My start script is
"tsc-watch -p ./server onSuccess \"cross-env NODE_ENV=development node dist/server/server.js\""

./server has a server.ts, a tsconfig.json and a bunch of other folders and ts files.

So how can I use tsc-watch to compile a specific directory with its tsconfig.json if I cannot make use of the -p option?

node app not killed by killer.js

Hello,
we are developing a nest app (inside a docker container). Everything works fine with tsc-watch but when code is being changed, dist is being rebuilt, the node process is not restarted.

The relevant code is package.json is

"scripts": {
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "tsc-watch -p tsconfig.build.json --onSuccess 'node dist/main.js'",
  },

we are using start:dev.

We have tracked down the problem to the killer.js source file issueing a SIGUSR2 signal to node. Our basic node app does not handle this signal so it just ignores the signal, and does not die.

Maybe it's because nest handles SIGUSR2 in its own way. We don't know.

We have solved the issue in two ways:

  1. changing killer.js (killer.js) to have let KILL_SIGNAL = 'SIGTERM';
  2. adding a process.on('SIGUSR2', () => { process.exit();}); to our main.ts app file.

Either way makes the tsc-watch work as expected

But we are wondering why you put SIGUSR instead of SIGTERM, or what are we missing, since nobody seems to have our problem.
Could you help us better understand the basic issue here? Thanks.

Anyway thanks for your work for the node community,
regards

1.0.8 breaks flag usage on onSuccess

Previously with v1.0.7, the following command would work:

tsc-watch --onSuccess \"node -r dotenv/config dist/index.js\"

As of 1.0.8 it fails with the following error message:

yarn dev v0.27.5
$ tsc-watch --onSuccess "node -r dotenv/config dist/index.js"
env: node\r: No such file or directory
error Command failed with exit code 127.

killer is not defined

I'm having this error:

  ReferenceError: killer is not defined
  at kill (node_modules/tsc-watch/lib/runner.js:20:20)
  at killProcesses (node_modules/tsc-watch/lib/tsc-watch.js:24:21)
  at Socket.tscProcess.stdout.on.buffer (node_modules/tsc-watch/lib/tsc-watch.js:51:5)
  at Socket.emit (events.js:189:13)
  at addChunk (_stream_readable.js:284:12)
  at readableAddChunk (_stream_readable.js:265:11)
  at Socket.Readable.push (_stream_readable.js:220:10)
  at Pipe.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
node_modules/tsc-watch/lib/runner.js:20
  return Promise.all([killer(process), exitPromise]);

The file: tsc-watch/lib/runner.js
is missing this line, perhaps?

const killer = require('./killer')

Formatting of terminal output is not ideal

A few minor issues with the formatting of the terminal output :-)

After initial build:

  • Only the [ is colored. It would be better to color the whole line, except for the gray timestamp.

image

After rebuilding:

  • Two line breaks and a separator line is added. This might make sense when history is preserved, but when it clears the console before each build, it just seems weird and noisy.
  • Again, only the [ is colored.
  • A single line break before and after the errors would improve readability.

image

I'm on macOS by the way.

No restarts after changes.

After updating to 1.0.29, I'm not getting any recompiles when I change files, even if I run something short-lived, as below:

tsc-watch --preserveWatchOutput --onSuccess 'echo hello'

TOO MANY NODES!?!?

One problem is this doesn't kill the old process it ran, so if you start a node server it will just start more, not terminating the old ones

tsc-watch does not quit on CTRL+C

tsc-watch does not seem to properly quit on ctrl+c. then at some point if I change some file, it randomly prints stuff like this to console:

----------------------
1:16:00 PM - File change detected. Starting incremental compilation...
1:16:00 PM - Found 0 errors. Watching for file changes.
Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
    at process.target.send (internal/child_process.js:678:16)
    at Object.Signal.send (~/gui/node_modules/tsc-watch/lib/tsc-watch.js:81:64)
    at Object.emitSuccess (~/gui/node_modules/tsc-watch/lib/tsc-watch.js:84:12)
    at ~/gui/node_modules/tsc-watch/lib/tsc-watch.js:68:16
    at processTicksAndRejections (internal/process/task_queues.js:89:5)

Running tsc-watch programmatically by creating an instance of TscWatchClient.

You think I need to kill it manually on exit? i.e:

process.on('SIGINT', () => {
  watch.kill();
  process.exit();
});

v1.0.19 Needs a revert :X

Since upgrading from v1.0.18 to v1.0.19 I've noticed two things.

  1. The --onSuccess hook never gets called when a compilation error occurs. Maybe look up the noEmitOnError field in the project's tsconfig.json.
  2. You're toying with my console by modifying colors and such. lol I've been using this for so long now, that change is something I'm not used to and my reflexes immediately make me think there's an error. Kinda goes nicely with my tsc-wtf project.

Hope you're OK with hearing constructive criticism. I absolutely love the work you've done on this project and I use it every single day. Cheers mate! :D

1.0.27 -> 1.0.28 regression

Looks like something broke in 1.0.28.

Look at:

if (fullCommand) {
const parts = stringArgv(fullCommand);
const exec = parts[0];
const args = parts.splice(1);
return spawn(exec, parts, {
stdio: 'inherit'
})
}

I think you either want:

    const args = parts.splice(0, 1);
    return spawn(exec, parts, {

or

    const args = parts.slice(1);
    return spawn(exec, args, {

run without --watch

Hi there, im using this plugin to get the success callback and start my node server after the compiler is done. For dev its ok, because i need the --watch flag, but for building purposes, i dont need to watch, just need the success callback, would be great to have the option to disable --watch, do you plan to do that?

Output colors is not same as tsc --watch

This seems like a nice lib and I will give it a try :-).

I'm using vscode integrated terminal with solarized light settings. The colors of the output is not the same of regular tsc --watch and tsc-watch, see below. The colors output by tsc-watch is very hard to read with my settings.

$ yarn tsc --watch

image

$ yarn tsc-watch

image

Watch additional files.

It'd be great to be able to specify additional files, outside of those included by tsc that are watched by this process.

E.g., if I make changes to a .graphql file somewhere in my directory tree, I'd like to have the watch process restart node without having tsc try to compile the file.

I have a feeling this will require integrating the better part of nodemon in order to get queued file system events across OS platforms. Sorry, no pull request today. Just recording the feature request for now.

lib/stdout-manipulator.js

In windows there are to many empty line in the console output. This can be fixed by replacing the manipulate function in stdout-manipulator.js to this:

function manipulate(buffer) {
const lines = buffer
.toString()
.split(/\r\n|\n|\r/gm)
.filter(a => a.length > 0)
.map(a => a.replace(tscUsageSyntaxRegex, newAdditionToSyntax));

return lines;
}

output before:

Web Server is running
09:37:14 - Starting compilation in watch mode...

09:37:15 - Found 0 errors. Watching for file changes.
Running webpack...
Webpack done!

output after changing the code:

Web Server is running
09:44:17 - Starting compilation in watch mode...
09:44:18 - Found 0 errors. Watching for file changes.
Running webpack...
Webpack done!

Hoop you can change that in a future release.

Incorrect version of tsc used

I upgraded a project to typescript 2.9.1 and encountered a strange behavior. It seems tsc-watch is still using typescript 2.8.3 but I don't understand where it finds it. This is on Windows 10.

Some output:

$ tsc-watch --version
Version 2.6.2

$ tsc --version
Version 2.9.1

$ yarn tsc-watch --version
yarn run v1.7.0
$ C:\code\XXX\node_modules\.bin\tsc-watch --version
Version 2.8.3

$ yarn tsc --version
yarn run v1.7.0
$ C:\code\XXX\node_modules\.bin\tsc --version
Version 2.9.1

$ which tsc
/c/Users/jonkel.DIVID/AppData/Roaming/npm/tsc

$ /c/Users/jonkel.DIVID/AppData/Roaming/npm/tsc --version
Version 2.9.1

$ yarn which tsc
yarn run v1.7.0
$ C:\code\XXX\node_modules\.bin\which tsc
C:\code\XXX\node_modules\.bin\tsc.CMD

I'm trying to find out where tsc-watch is finding the old tsc binary. It seems it is not looking at the global path or at the path yarn sets.

[Typescript version 2.7.2] onSuccess and onFailure callbacks do not seem to work

In my package.json I have the following script defined:

"scripts": {
  "build": "cd someSubFolder && tsc-watch --onSuccess \"echo Success\" --onFailure \"echo Failure\""
}

When I run npm run build the TypeScript compilation seems to work along with the watch mode, however none of the two callbacks gets fired. What am I missing?

I am using typescript 2.7.2 and tsc-watch 2.2.1

typescript should be a peerDependency

This is related to #28. That one was closed when the author saw that yarn was giving tsc-watch its own private copy of typescript (of a different version).

However, yarn's choice to do so was valid (and npm may do the same thing), as tsc-watch declares a direct dependency on typescript.

peerDependencies is a better model for what tsc-watch is trying to do -- i.e., "I will take the copy of typescript that you've already installed, and run it for you".

ERR_IPC_CHANNEL_CLOSED error

Hi,

I observe the ERR_IPC_CHANNEL_CLOSED error happening from time to time, which abruptly quits my watch script leaving all spawned child processes active. (using tsc-watch v2.1.1)

Do you have any ideas to why that may be happening?

Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
    at process.target.send (internal/child_process.js:644:16)
    at Object.Signal.send.process.send.function.e [as send] (~/app/node_modules/tsc-watch/lib/tsc-watch.js:77:64)
    at Object.emitSuccess (~/app/node_modules/tsc-watch/lib/tsc-watch.js:80:12)
    at killProcesses.then (~/app/node_modules/tsc-watch/lib/tsc-watch.js:64:16)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)

That's my watch script:
https://github.com/mullvad/mullvadvpn-app/blob/master/gui/packages/desktop/scripts/serve.js

Custom compiler support

The tsc-watch i awesome but has a hard-written compiler name:
File lib/tsc-watch.js Line 129:
const bin = require.resolve('typescript/bin/tsc');

but there are other compilers compatible with typescript for example ntypescript, ttypescript.

Webpack plugin - awesome-typescript-loader allows you to choose a compiler by an optional parameter:
--compiler (string) (default='typescript')

Could you have parameterized tsc-watch in a similar way?

Please export a tsc-watch/client class

Hi,

Currently tsc-watch/client exports a singleton. It makes it impossible to run multiple tsc-watch side by side. This is especially critical in the workspace configuration. Would it be possible to export the class itself instead of an instance?

Release tagging

Hi!

I was wondering if it would be possible to tag releases? I wanted to peek at a diff between two old versions was bummed to see only a single tagged release.

Future versions were tagged that would be helpful going forward, but I think it might not be too difficult to tag old releases assuming your changelog commits are accurate.

Since I can't propose tags via the PR process, a contributor would have to check out each of the dozen version refs from the changelog and run git tag 1.x.x and then push tags. It's PITA but it's 5mins for much better transparency.

Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.