Skip to content

Commit d4c9100

Browse files
committed
add error recompile
1 parent 06b9759 commit d4c9100

File tree

8 files changed

+97
-12
lines changed

8 files changed

+97
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ tsnd --respawn server.ts
4141

4242
- `--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.
4343
- `--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.
44-
So, to ignore everything in `node_modules`, just pass `--ignore-watch node_modules`.
44+
So, to ignore everything in `node_modules`, just pass `--ignore-watch node_modules`, or us `--no-deps` for the same effect.
4545

4646
- `--debug` - Some additional debug output.
4747
- `--interval` - Polling interval (ms)

lib/compiler.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var extHandlers = {}
2828
var compiler = {
2929
allowJs: false,
3030
tsConfigPath: '',
31+
_errorCompileTimeout: 0,
3132
getCompilationId: function () {
3233
return compilationInstanceStamp
3334
},
@@ -122,6 +123,9 @@ var compiler = {
122123
)
123124
fs.writeFileSync(compiler.getChildHookPath(), fileData)
124125
},
126+
clearErrorCompile: () => {
127+
clearTimeout(compiler._errorCompileTimeout)
128+
},
125129
init: function (options) {
126130
compiler.options = options
127131
var project = options['project']
@@ -201,7 +205,7 @@ var compiler = {
201205
files: options['files'] || true,
202206
}
203207
try {
204-
compiler.service = register(tsNodeOptions)
208+
compiler.service = register(tsNodeOptions)
205209
} catch (e) {
206210
console.log(e)
207211
return
@@ -244,7 +248,7 @@ var compiler = {
244248
var m = {
245249
_compile: writeCompiled,
246250
}
247-
try {
251+
const _compile = () => {
248252
var ext = path.extname(fileName)
249253
var extHandler = extHandlers[ext]
250254
extHandler(m, fileName)
@@ -255,12 +259,33 @@ var compiler = {
255259
new Date().getTime() - starTime,
256260
'ms'
257261
)
262+
}
263+
try {
264+
_compile()
258265
} catch (e) {
259266
console.log('Compilation error in', fileName)
260267
const errorCode =
261268
'throw ' + 'new Error(' + JSON.stringify(e.message) + ')' + ';'
262269
writeCompiled(errorCode)
270+
// should we really re-register ts-node?
263271
compiler.registerTsNode()
272+
273+
const timeoutMs =
274+
parseInt(process.env.TS_NODE_DEV_ERROR_RECOMPILE_TIMEOUT) || 2500
275+
const errorHandler = () => {
276+
clearTimeout(compiler._errorCompileTimeout)
277+
compiler._errorCompileTimeout = setTimeout(() => {
278+
try {
279+
_compile()
280+
compiler.restart(fileName)
281+
} catch (e) {
282+
compiler.registerTsNode()
283+
errorHandler()
284+
}
285+
}, timeoutMs)
286+
}
287+
288+
errorHandler()
264289
}
265290
},
266291
}

lib/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ module.exports = function(script, scriptArgs, nodeArgs, opts) {
7272
output: process.stdout,
7373
terminal: false
7474
})
75-
rl.on('line', function(line) {
76-
console.log('rl.on line', line)
75+
rl.on('line', function(line) {
7776
if (line.trim() === 'rs') {
7877
restart('', true)
7978
}
@@ -205,6 +204,7 @@ module.exports = function(script, scriptArgs, nodeArgs, opts) {
205204
notify('Reinitializing TS compilation')
206205
compiler.init(opts)
207206
}
207+
compiler.clearErrorCompile()
208208
/* eslint-disable no-octal-escape */
209209
if (cfg.clear) process.stdout.write('\033[2J\033[H')
210210
if (isManualRestart === true) {
@@ -232,6 +232,7 @@ module.exports = function(script, scriptArgs, nodeArgs, opts) {
232232
start()
233233
}
234234
}
235+
compiler.restart = restart
235236

236237
// Relay SIGTERM
237238
process.on('SIGTERM', function() {

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
"node": ">=0.8.0"
3838
},
3939
"scripts": {
40-
"tsnd": "node ./bin/ts-node-dev",
4140
"ts-node-dev": "node ./bin/ts-node-dev",
41+
"tsnd": "yarn ts-node-dev",
4242
"test": "ts-node --transpile-only test/index.ts",
4343
"ci": "yarn test",
4444
"manual": "node ./bin/ts-node-dev --rt 5 --exit-child --tree-kill --clear -r tsconfig-paths/register -r ./test/manual/add-require -r ./test/manual/add-require-2 -r esm -O \"{\\\"module\\\": \\\"es6\\\"}\" --preserve-symlinks --respawn --ignore-watch 'lib' --ignore-watch bin --prefer-ts --debug --poll --interval 1000 --cache-directory .ts-node --inspect -- test/manual/test-script test-arg --fd"
@@ -47,8 +47,8 @@
4747
"chokidar": "^3.4.0",
4848
"dateformat": "~1.0.4-1.2.3",
4949
"dynamic-dedupe": "^0.3.0",
50-
"minimist": "^1.1.3",
51-
"mkdirp": "^0.5.1",
50+
"minimist": "^1.2.5",
51+
"mkdirp": "^1.0.4",
5252
"node-notifier": "^5.4.0",
5353
"resolve": "^1.0.0",
5454
"rimraf": "^2.6.1",

test/fixture/with-not-found.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { fn } from './not-found'
2+
3+
console.log(fn(1))

test/index.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ const replaceText = async (
1717
return fs.writeFile(textFile, text.replace(pattern, replace))
1818
}
1919

20+
const writeFile = async (script: string, text: string) => {
21+
const textFile = join(scriptsDir, script)
22+
return fs.writeFile(textFile, text)
23+
}
24+
25+
const removeFile = async (script: string) => {
26+
const textFile = join(scriptsDir, script)
27+
return fs.remove(textFile)
28+
}
29+
2030
const waitFor = (timeout: number) => {
2131
return new Promise((resolve) => setTimeout(resolve, timeout))
2232
}
@@ -47,12 +57,14 @@ fs.copySync(join(__dirname, 'fixture'), scriptsDir)
4757
*/
4858

4959
test('It should restart on file change', async (t) => {
50-
const ps = spawnTsNodeDev('--respawn --poll simple.ts', {stdout: true})
60+
const ps = spawnTsNodeDev('--respawn --poll simple.ts')
5161
await ps.waitForLine(/v1/)
5262
setTimeout(() => replaceText('dep.ts', 'v1', 'v2'), 250)
5363
await ps.waitForLine(/v2/)
5464
t.pass('Changed code version applied.')
5565
await ps.exit()
66+
// revert
67+
replaceText('dep.ts', 'v2', 'v1')
5668
})
5769

5870
test('It allow watch arbitrary folder/file', async (t) => {
@@ -80,4 +92,44 @@ test('It should report an error on start', async (t) => {
8092
await ps.waitForLine(/v1/)
8193
t.pass('Restarted successfully after error fixed.')
8294
await ps.exit()
95+
replaceText('with-error.ts', '1', `'1'`)
96+
})
97+
98+
test('It restart on non imported file', async (t) => {
99+
const ps = spawnTsNodeDev('--respawn with-error.ts', {
100+
//stdout: true,
101+
env: {
102+
TS_NODE_DEV_ERROR_RECOMPILE_TIMEOUT: 500,
103+
},
104+
})
105+
await ps.waitForLine(/[ERROR]/)
106+
107+
setTimeout(() => replaceText('dep-ts-error.ts', 'number', 'string'), 250)
108+
109+
await ps.waitForLine(/v1/)
110+
t.pass('Restarted successfully after error fixed.')
111+
await ps.exit()
112+
replaceText('dep-ts-error.ts', 'string', 'number')
113+
})
114+
115+
const notFoundSource = `export const fn = (x: number) => {
116+
return 'v1'
117+
}
118+
`
119+
120+
test('It restarts when not found module added', async (t) => {
121+
const ps = spawnTsNodeDev('--respawn with-not-found.ts', {
122+
//stdout: true,
123+
env: {
124+
TS_NODE_DEV_ERROR_RECOMPILE_TIMEOUT: 250,
125+
},
126+
})
127+
await ps.waitForLine(/[ERROR]/)
128+
129+
setTimeout(() => writeFile('not-found.ts', notFoundSource), 1000)
130+
131+
await ps.waitForLine(/v1/)
132+
t.pass('Restarted successfully after error fixed.')
133+
await ps.exit()
134+
await removeFile('not-found.ts')
83135
})

test/spawn.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ const scriptsDir = path.join(__dirname, '/../.temp/fixture')
77

88
export const spawnTsNodeDev = (
99
cmd: string,
10-
opts: { stdout?: boolean; stderr?: boolean } = {}
10+
opts: { stdout?: boolean; stderr?: boolean; env?: any } = {}
1111
) => {
1212
const nodeArg = [bin].concat(cmd.split(' '))
13-
const ps = child.spawn('node', nodeArg, { cwd: scriptsDir })
13+
const ps = child.spawn('node', nodeArg, { cwd: scriptsDir, env: opts.env })
1414
var out = ''
1515
var err = ''
1616

@@ -41,7 +41,6 @@ export const spawnTsNodeDev = (
4141
return new Promise((resolve) => {
4242
const listener = (data: string) => {
4343
const line = data.toString()
44-
console.log('line', line)
4544
if (testPattern(pattern, line)) {
4645
ps.stdout.removeListener('data', listener)
4746
resolve(line)

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,6 +1849,11 @@ [email protected], mkdirp@^0.5.0, mkdirp@^0.5.1:
18491849
dependencies:
18501850
minimist "0.0.8"
18511851

1852+
mkdirp@^1.0.4:
1853+
version "1.0.4"
1854+
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
1855+
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
1856+
18521857
18531858
version "2.0.0"
18541859
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"

0 commit comments

Comments
 (0)