Skip to content

Commit ad97a41

Browse files
committed
--debug, --exec-check
1 parent 3641048 commit ad97a41

File tree

11 files changed

+103
-80
lines changed

11 files changed

+103
-80
lines changed

README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,51 @@ It restarts target node process when any of required files changes (as standard
77
## Install
88

99
```
10-
yarn add ts-node-dev
10+
yarn add ts-node-dev --dev
1111
```
1212

1313
```
14-
npm i ts-node-dev
14+
npm i ts-node-dev --save-dev
1515
```
1616

1717
`ts-node` dependency version is not fixed, so it will install the latest version by default.
1818

1919
## Usage
2020

2121
```
22-
ts-node-dev [node-dev|ts-node flags] [ts-node-dev flags] [script] [script arguments]
22+
ts-node-dev [node-dev|ts-node flags] [ts-node-dev flags] [node cli flags] [--] [script] [script arguments]
2323
```
2424

2525
So you just combine [node-dev](https://github.com/fgnass/node-dev) and [ts-node](https://github.com/TypeStrong/ts-node) options (see docs of those packages):
2626
```
2727
ts-node-dev --respawn --transpileOnly server.ts
2828
```
2929

30-
Also there are additional options specific to `ts-node-dev`:
30+
There is also short alias `tsnd` for running `ts-node-dev`:
31+
32+
```
33+
tsnd --respawn server.ts
34+
```
35+
36+
**Also there are additional options specific to `ts-node-dev`:**
3137

3238
- `--prefer-ts` (default: false) - for each `.js` file (that is not in `node_modules`) will try to check if corresponding `.ts` version exists and require it.
3339
- `--ignore-watch` (default: []) - files/folders to be [ignored by `node-dev`](https://github.com/fgnass/node-dev#ignore-paths). **But also this behaviour enhanced:** it will also make up `new RegExp` of passed ignore string and check absolute paths of required files for match.
34-
So, to ignore everthing in `node_modules`, just pass `--ignore-watch node_modules`
40+
So, to ignore everthing in `node_modules`, just pass `--ignore-watch node_modules`.
41+
42+
- `--debug` - some additional debug output.
43+
44+
**And some points to notice:**
45+
46+
- `--ignore-watch` will NOT affect files ignored by TS compilation. Use `--ignore` option (or `TS_NODE_IGNORE` env variable) to pass **RegExp strings** for filtering files that should not be compiled, by default `/node_modules/` are ignored.
3547

36-
NB! `--ignore-watch` will NOT affect files ignored by TS compilation. Use `--ignore` option (or `TS_NODE_IGNORE` env variable) to pass **RegExp strings** for filtering files that should not be compiled, by default `/node_modules/` are ignored.
48+
- Unknown flags (`node` cli flags are considered to be so) are treated like string value flags by default. The right solution to avoid ambiguity is to separate script name from option flags with `--`, for example:
3749

38-
## Caveats
50+
```
51+
ts-node-dev --inspect -- my-script.ts
52+
```
3953

40-
The good thing is that `ts-node-dev` watches used `tsconfig.json` file, and will reinitialize compilation on its change, but you have to restart the process manually when you update used version of `typescript` or make any other changes that may effect compilation results.
54+
- The good thing is that `ts-node-dev` watches used `tsconfig.json` file, and will reinitialize compilation on its change, but you have to restart the process manually when you update used version of `typescript` or make any other changes that may effect compilation results.
4155

4256
## License
4357

bin/ts-node-dev

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ var opts = minimist(devArgs, {
1515
'cache', 'type-check',
1616
'prefer-ts',
1717
'transpileOnly',
18-
'files'
18+
'files',
19+
'exec-check',
20+
'debug'
1921
],
2022
string: [
2123
'compiler', 'project', 'ignore',

lib/cfg.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ module.exports = function (main, opts) {
3131

3232
var ignoreWatch = ([]).concat(opts && opts['ignore-watch'] || []);
3333
ignoreWatch.length && console.log('Ignore watch:', ignoreWatch)
34-
var ignore = ignoreWatch.concat(ignoreWatch.map(resolvePath));
35-
34+
var ignore = ignoreWatch.concat(ignoreWatch.map(resolvePath));
3635
return {
3736
vm: c.vm !== false,
3837
fork: c.fork !== false,
@@ -43,6 +42,7 @@ module.exports = function (main, opts) {
4342
dedupe: !!c.dedupe,
4443
ignore: ignore,
4544
respawn: c.respawn || false,
45+
debug: opts.debug,
4646
extensions: c.extensions || {
4747
coffee: 'coffee-script/register',
4848
ls: 'LiveScript'

lib/child-require-hook.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,34 @@ var sep = require('path').sep
44
var join = require('path').join
55
var execSync = require('child_process').execSync
66
var compilationId
7-
var timeThreshold = 10000
7+
var timeThreshold = 0
88
var allowJs = false
99
var compiledDir
1010
var preferTs = false
1111
var ignore = [/node_modules/]
1212
var readyFile
13+
var execCheck = false
1314

1415
var checkFileScript = join(__dirname, 'check-file-exists.js')
1516

17+
var waitForFile = function (fileName) {
18+
var start = new Date().getTime()
19+
while (true) {
20+
const exists = execCheck
21+
? execSync(['node', checkFileScript, '"' + fileName + '"'].join(' '), { stdio: 'inherit' })
22+
: fs.existsSync(fileName)
23+
if (exists) {
24+
return
25+
}
26+
var passed = (new Date().getTime() - start)
27+
if (timeThreshold && passed > timeThreshold) {
28+
throw new Error(
29+
'Could not require ' + fileName
30+
)
31+
}
32+
}
33+
}
34+
1635
var compile = (code, fileName) => {
1736
var compiledPath = getCompiledPath(code, fileName, compiledDir)
1837
process.send({
@@ -21,7 +40,7 @@ var compile = (code, fileName) => {
2140
})
2241
var compileRequestFile = [compiledDir, compilationId + '.req'].join(sep)
2342
fs.writeFileSync(compileRequestFile, [fileName, compiledPath].join('\n'))
24-
execSync(['node', checkFileScript, '"' + compiledPath + '.done' + '"'].join(' '), { stdio: 'inherit' })
43+
waitForFile(compiledPath + '.done')
2544
var compiled = fs.readFileSync(compiledPath, 'utf-8')
2645
return compiled
2746
}

lib/compiler.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ var compiler = {
5252
if (options['prefer-ts']) {
5353
fileData = fileData.replace('preferTs = false', 'preferTs = true')
5454
}
55+
if (options['exec-check']) {
56+
fileData = fileData.replace('execCheck = false', 'execCheck = true')
57+
}
5558
if (options['ignore'] !== undefined) {
5659
var ignore = options['ignore']
5760
var ignoreVal = !ignore || ignore === 'false'

lib/index.js

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var resolveMain = require('./resolveMain');
55
var compiler = require('./compiler');
66
var fs = require('fs');
77

8-
module.exports = function (script, scriptArgs, nodeArgs, opts) {
8+
module.exports = function (script, scriptArgs, nodeArgs, opts) {
99
compiler.init(opts)
1010
if (typeof script !== 'string' || script.length === 0) {
1111
throw new TypeError('`script` must be a string');
@@ -26,9 +26,9 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
2626
var main = resolveMain(script);
2727
var cfg = require('./cfg')(main, opts);
2828
var log = require('./log')(cfg);
29-
var notify = require('./notify')(cfg, log);
29+
var notify = require('./notify')(cfg, log);
3030
compiler.notify = notify
31-
compiler.stop = stop
31+
compiler.stop = stop
3232
// Run ./dedupe.js as preload script
3333
if (cfg.dedupe) process.env.NODE_DEV_PRELOAD = __dirname + '/dedupe';
3434

@@ -38,20 +38,20 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
3838
if (file === compiler.tsConfigPath) {
3939
notify('Reinitializing TS compilation');
4040
compiler.init(opts);
41-
}
41+
}
4242
/* eslint-disable no-octal-escape */
4343
if (cfg.clear) process.stdout.write('\033[2J\033[H');
4444
notify('Restarting', file + ' has been modified');
45-
compiler.compileChanged(file)
45+
compiler.compileChanged(file)
4646
if (starting) return
4747
watcher.removeAll();
4848
starting = true
4949
if (child) {
50-
// Child is still running, restart upon exit
50+
log.debug('Child is still running, restart upon exit')
5151
child.on('exit', start);
5252
stop();
5353
} else {
54-
// Child is already stopped, probably due to a previous error
54+
log.debug('Child is already stopped, probably due to a previous error')
5555
start();
5656
}
5757
});
@@ -66,10 +66,11 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
6666
/**
6767
* Run the wrapped script.
6868
*/
69-
function start() {
70-
var cmd = nodeArgs.concat(wrapper, script, scriptArgs);
69+
function start() {
70+
var cmd = nodeArgs.concat(wrapper, script, scriptArgs);
7171
var childHookPath = compiler.getChildHookPath();
7272
cmd = ['-r', childHookPath].concat(cmd);
73+
log.debug('Starting child process %s', cmd.join(' '))
7374
child = fork(cmd[0], cmd.slice(1), {
7475
cwd: process.cwd(),
7576
env: process.env
@@ -79,10 +80,10 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
7980
var currentCompilePath
8081
fs.writeFileSync(compiler.getCompileReqFilePath(), '');
8182
compileReqWatcher.add(compiler.getCompileReqFilePath());
82-
compileReqWatcher.on('change', function (file) {
83+
compileReqWatcher.on('change', function (file) {
8384
fs.readFile(file, 'utf-8', function (err, data) {
8485
if (err) {
85-
console.log('Error reading compile request file', err)
86+
log.error('Error reading compile request file', err)
8687
return
8788
}
8889
var split = data.split('\n')
@@ -104,8 +105,9 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
104105
currentCompilePath = message.compiledPath
105106
compiler.compile(message)
106107
});
107-
108+
108109
child.on('exit', function (code) {
110+
log.debug('Child exited with code %s', code)
109111
if (!child) return
110112
if (!child.respawn) process.exit(code);
111113
child = undefined;
@@ -115,10 +117,11 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
115117
child.respawn = true;
116118
}
117119

118-
if (!compiler.tsConfigPath) {
119-
throw new Error('Check existance of tsconfig.json file.')
120+
121+
if (compiler.tsConfigPath) {
122+
watcher.add(compiler.tsConfigPath);
120123
}
121-
watcher.add(compiler.tsConfigPath);
124+
122125

123126
// Listen for `required` messages and watch the required file.
124127
ipc.on(child, 'required', function (m) {
@@ -142,11 +145,15 @@ module.exports = function (script, scriptArgs, nodeArgs, opts) {
142145
return
143146
};
144147
child.stopping = true
145-
child.respawn = true;
148+
child.respawn = true;
146149
if (child.connected === undefined || child.connected === true) {
150+
log.debug('Disconnecting from child')
147151
child.disconnect();
148-
if (!willTerminate) child.kill('SIGTERM');
149-
}
152+
if (!willTerminate) {
153+
log.debug('Sending SIGTERM kill to child')
154+
child.kill('SIGTERM');
155+
}
156+
}
150157
}
151158

152159
// Relay SIGTERM

lib/log.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ var fmt = require('dateformat');
44
var colors = {
55
info: '36',
66
error: '31;1',
7-
warn: '33'
7+
warn: '33',
8+
debug: '90'
89
};
910

1011
/**
@@ -26,6 +27,11 @@ module.exports = function (cfg) {
2627
return s;
2728
}
2829

30+
log.debug = function () {
31+
if (!cfg.debug) return
32+
log(util.format.apply(util, arguments), 'debug');
33+
};
34+
2935
log.info = function () {
3036
log(util.format.apply(util, arguments), 'info');
3137
};

lib/wrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ process.argv.splice(1, 1);
1212
// Resolve the location of the main script relative to cwd
1313
var main = resolveMain(process.argv[1]);
1414

15-
var cfg = require('./cfg')(main);
15+
var cfg = require('./cfg')(main, {});
1616

1717
// Set NODE_ENV to 'development' unless already set
1818
if (!process.env.NODE_ENV) process.env.NODE_ENV = 'development';

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
},
2020
"license": "MIT",
2121
"bin": {
22-
"ts-node-dev": "./bin/ts-node-dev"
22+
"ts-node-dev": "./bin/ts-node-dev",
23+
"tsnd": "./bin/ts-node-dev"
2324
},
2425
"main": "./lib",
2526
"files": [
@@ -34,7 +35,7 @@
3435
"scripts": {
3536
"ts-node-dev": "node ./bin/ts-node-dev",
3637
"test-node-dev": "tap test/*.js",
37-
"test": "node ./bin/ts-node-dev -r tsconfig-paths/register -r ./test/ts/add-require.js -r ./test/ts/add-require-2.js -O \"{\\\"module\\\": \\\"commonjs\\\"}\" --respawn --ignore-watch 'lib' --ignore-watch bin --prefer-ts --cache-directory .ts-node test/ts/test-script test-arg --fd",
38+
"test": "node ./bin/ts-node-dev -r tsconfig-paths/register -r ./test/ts/add-require.js -r ./test/ts/add-require-2.js -O \"{\\\"module\\\": \\\"commonjs\\\"}\" --respawn --ignore-watch 'lib' --ignore-watch bin --prefer-ts --debug --cache-directory .ts-node --inspect -- test/ts/test-script test-arg --fd",
3839
"test-docker": "docker run --rm -v ${PWD}:/app mhart/alpine-node:8.7.0 sh -c 'cd app && node ./bin/ts-node-dev --cache-directory .ts-node test/ts/big'"
3940
},
4041
"dependencies": {

test/ts/test-script.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {fn} from './dep'
22

33
const str: string = process.argv[2]
4-
console.log('test3', str)
5-
//
6-
fn()
4+
console.log('test', str)
5+
6+
//fn()

0 commit comments

Comments
 (0)