electronmon
Advanced tools
Comparing version 0.4.0 to 0.5.0
{ | ||
"name": "electronmon", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "watch and reload your electron app the easy way", | ||
@@ -33,3 +33,3 @@ "main": "src/electronmon.js", | ||
"eslint": "^5.16.0", | ||
"mocha": "^6.1.4", | ||
"mocha": "^6.2.1", | ||
"node-stream": "^1.7.0", | ||
@@ -42,3 +42,3 @@ "touch": "^3.1.0", | ||
"chalk": "^2.4.2", | ||
"chokidar": "^2.1.5", | ||
"chokidar": "^2.1.8", | ||
"import-from": "^2.1.0", | ||
@@ -45,0 +45,0 @@ "runtime-required": "^1.0.2" |
@@ -25,3 +25,3 @@ # electronmon | ||
To use it, you don't have to change your application at all. Just use `electronmon` to launch it, using all the same arguments you would pass to the `electron` cli: | ||
To use it, you don't have to change your application at all. Just use `electronmon` instead of `electron` to launch your application, using all the same arguments you would pass to the `electron` cli: | ||
@@ -35,1 +35,5 @@ ```bash | ||
All you have to do now is write your application code. | ||
## Supported environments | ||
This module is tested and supported on Windows, MacOS, and Linux, using node versions 8, 10, and 12 and electron versions 3, 4, 5, and 6. |
@@ -10,7 +10,32 @@ const path = require('path'); | ||
const signal = require('./signal.js'); | ||
const ignore = -1; | ||
const errored = -1; | ||
const isTTY = process.stdout.isTTY && process.stderr.isTTY; | ||
const env = Object.assign(isTTY ? { FORCE_COLOR: '1' } : {}, process.env); | ||
const appfiles = {}; | ||
let globalApp; | ||
let overrideSignal; | ||
function onTerm() { | ||
if (globalApp) { | ||
globalApp.kill('SIGINT'); | ||
} | ||
process.exit(0); | ||
} | ||
function onMessage({ type, file }) { | ||
if (type === 'discover') { | ||
appfiles[file] = true; | ||
} else if (type === 'uncaught-exception') { | ||
log.info('uncaught exception occured'); | ||
log.info('waiting for any change to restart the app'); | ||
overrideSignal = errored; | ||
} | ||
} | ||
function startApp() { | ||
overrideSignal = null; | ||
const hook = path.resolve(__dirname, 'hook.js'); | ||
@@ -25,85 +50,79 @@ const args = ['--require', hook].concat(argv); | ||
return app; | ||
} | ||
app.on('message', onMessage); | ||
function waitForChange() { | ||
const watcher = watch(); | ||
app.once('exit', code => { | ||
process.removeListener('SIGTERM', onTerm); | ||
process.removeListener('SIGHUP', onTerm); | ||
globalApp = null; | ||
watcher.on('change', relpath => { | ||
log.info(`file change: ${relpath}`); | ||
watcher.close(); | ||
if (overrideSignal === errored) { | ||
log.info(`ignoring exit with code ${code}`); | ||
return; | ||
} | ||
module.exports(); | ||
if (overrideSignal === signal || code === signal) { | ||
log.info('restarting app due to file change'); | ||
startApp(); | ||
return; | ||
} | ||
log.info(`app exited with code ${code}, waiting for change to restart it`); | ||
}); | ||
watcher.once('ready', () => { | ||
log.info('waiting for a change to restart it'); | ||
}); | ||
process.once('SIGTERM', onTerm); | ||
process.once('SIGHUP', onTerm); | ||
globalApp = app; | ||
return app; | ||
} | ||
function watchApp(app) { | ||
let overrideSignal = null; | ||
function restartApp() { | ||
globalApp.once('exit', () => { | ||
startApp(); | ||
}); | ||
const onTerm = () => { | ||
app.kill('SIGINT'); | ||
process.exit(0); | ||
}; | ||
globalApp.kill('SIGINT'); | ||
} | ||
const onMsg = msg => { | ||
if (msg === 'uncaught-exception') { | ||
log.info('uncaught exception occured'); | ||
overrideSignal = ignore; | ||
function startWatcher(done) { | ||
const watcher = watch(); | ||
const watcher = watch(); | ||
watcher.on('change', relpath => { | ||
const filepath = path.resolve('.', relpath); | ||
const type = 'change'; | ||
watcher.once('change', relpath => { | ||
log.info(`file change: ${relpath}`); | ||
if (overrideSignal === errored) { | ||
log.info(`file ${type}: ${relpath}`); | ||
return restartApp(); | ||
} | ||
if (app.connected) { | ||
// if the app is still running, set the signal override to the | ||
// regular restart signal and kill the app | ||
overrideSignal = signal; | ||
app.kill('SIGINT'); | ||
} else { | ||
// the app is no longer running, so do a clean start | ||
module.exports(); | ||
} | ||
}); | ||
if (!globalApp) { | ||
log.info(`file ${type}: ${relpath}`); | ||
return startApp(); | ||
} | ||
watcher.once('ready', () => { | ||
log.info('waiting for any change to restart the app'); | ||
}); | ||
if (appfiles[filepath]) { | ||
log.info(`main file ${type}: ${relpath}`); | ||
globalApp.send('reset'); | ||
} else { | ||
app.once('message', onMsg); | ||
log.info(`renderer file ${type}: ${relpath}`); | ||
globalApp.send('reload'); | ||
} | ||
}; | ||
}); | ||
app.once('message', onMsg); | ||
watcher.on('add', relpath => { | ||
log.verbose('watching new file:', relpath); | ||
}); | ||
app.once('exit', code => { | ||
process.removeListener('SIGTERM', onTerm); | ||
process.removeListener('SIGHUP', onTerm); | ||
watcher.once('ready', () => { | ||
log.info('waiting for a change to restart it'); | ||
if (overrideSignal === ignore) { | ||
return; | ||
if (done) { | ||
done(); | ||
} | ||
if (overrideSignal === signal || code === signal) { | ||
log.info('restarting app due to file change'); | ||
module.exports(); | ||
return; | ||
} | ||
log.info('app exited with code', code); | ||
waitForChange(); | ||
}); | ||
process.once('SIGTERM', onTerm); | ||
process.once('SIGHUP', onTerm); | ||
} | ||
module.exports = () => { | ||
watchApp(startApp()); | ||
startWatcher(() => startApp()); | ||
}; |
@@ -1,3 +0,1 @@ | ||
const path = require('path'); | ||
const electron = require('electron'); | ||
@@ -8,3 +6,3 @@ const required = require('runtime-required'); | ||
const signal = require('./signal.js'); | ||
const watcher = require('./watch.js')(); | ||
const queue = require('./message-queue.js'); | ||
@@ -21,32 +19,15 @@ const pathmap = {}; | ||
function relaunch() { | ||
function reset() { | ||
exit(signal); | ||
} | ||
watcher.on('add', relpath => { | ||
log.verbose('watching new file:', relpath); | ||
}); | ||
watcher.on('change', relpath => { | ||
const type = 'change'; | ||
const filepath = path.resolve('.', relpath); | ||
if (pathmap[filepath]) { | ||
log.info(`main file ${type}:`, relpath); | ||
return relaunch(); | ||
} | ||
log.info(`renderer file ${type}:`, relpath); | ||
function reload() { | ||
const windows = electron.BrowserWindow.getAllWindows(); | ||
if (windows && windows.length) { | ||
for (const win of electron.BrowserWindow.getAllWindows()) { | ||
for (const win of windows) { | ||
win.webContents.reloadIgnoringCache(); | ||
} | ||
} else { | ||
log.info('there are no windows to reload'); | ||
// relaunch(); | ||
} | ||
}); | ||
} | ||
@@ -66,14 +47,30 @@ required.on('file', ({ type, id }) => { | ||
pathmap[id] = true; | ||
watcher.add(id); | ||
queue({ type: 'discover', file: id }); | ||
}); | ||
process.on('message', msg => { | ||
if (msg === 'reset') { | ||
return reset(); | ||
} | ||
if (msg === 'reload') { | ||
return reload(); | ||
} | ||
log.verbose('unknown hook message:', msg); | ||
}); | ||
process.on('uncaughtException', err => { | ||
const name = electron.app.getName(); | ||
const onHandled = () => { | ||
electron.dialog.showErrorBox(`${name} encountered an error`, err.stack); | ||
exit(1); | ||
}; | ||
if (process.send) { | ||
process.send('uncaught-exception'); | ||
queue({ type: 'uncaught-exception' }, () => onHandled()); | ||
} else { | ||
onHandled(); | ||
} | ||
electron.dialog.showErrorBox(`${name} encountered an error`, err.stack); | ||
exit(1); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9096
9
218
38
Updatedchokidar@^2.1.8