I'm the owner of gulp-nodemon, and I'm looking for a way to build my app before it restarts without spawning child processes.
If I want to envify between restarts, I'd use nodemon({ exec: 'envify index.js' }). But the idea of gulp-nodemon is to keep all of your building system one process and the app itself in another.
Is there a way one can pause the restarting of nodemon until a task has finished executing?
+1
Proposal:
nodemon.on('restart?', function () {
// gulp-nodemon is now in control of whether nodemon restarts
// do some "stuff" then when you're ready (or not):
nodemon.emit('restart');
});
How does that sit?
Current implementation is looking like this (I think):
nodemon.on('restart?', function (restart) {
doOwnTask().then(restart);
});
The risk here is if two clients bind to the restart? event. It'll get very messy...I'm not quite sure right now.
What about:
nodemon.registerStartupInterruptor(function(done) {
doOwnTask().then(done);
});
Events aren't really the right tool for this, because they aren't designed to be "pause-able". So nodemon isn't just firing an event which anyone can listen to if they want and node takes care of running the event handlers; nodemon itself explicitly runs the "event handlers" so it knows when they're finished and can then actually do a restart. This means that nodemon can run them in series, in parallel, whatever it wants. However, it is a little bit wheel-reinventy.
Maybe if the restart that gets passed to the "restart?" event handler is a promise and nodemon gathers all the restart promises and does [restartobj1, restartobj2].all(actuallyRestart) ? (handwaving).
I agree with @stuartlangridge, events aren't the right way to handle this. registerStartupInterruptor doesn't seem very semantic, though. How about:
nodemon.handleRestart(function (done) {})
And there would be a couple of them for the most commonly paused events.
Resuming this conversation, I think I prefer the syntax that's a little more like middleware - which is what we're really talking about, like this:
nodemon.pre('restart', function (done) { /* ... */ });
I'm happy to push a development build in to npm for testing?
Thoughts? I'm not keen on named functions are interrupts and prefer "middleware" like code. Obviously if it doesn't call done, then the chain is broken, but that's the point, right?
Any update on this one?
Since no one came back to me, I didn't continue any dev on it.
We do have event hooks via nodemon.json, but I think you're requiring nodemon so that didn't benefit you.
The current event hooks happen after the event.
start = after startrestart = after restartbut I would like to request an event for before the start/restart/etc, something like
prestartprerestartor
before_startbefore_restartSo that I can have a script run that regenerates assets before the application gets restarted. In my case, I need the event to block the restart of the app.
So. If you scan back through the other comments I've dropped, an event doesn't make sense, because an event is "this thing happened and I'm going to carry on". Even if you hook a prestart event, your script will likely not be finished _before_ the start event fires.
This is why I suggested a pre method that you can then call the done callback to say to nodemon "go ahead, I'm ready for the actual event to happen now".
Ok, sorry I didn't read back and notice that. I probably should have searched the page. I only skimmed through all the comments.
However, I might suggest changing events. In most systems that I am familiar with that implement events, the system will wait for the event to complete. Also, events are typically run in the order they are registered. Perhaps a async flag that defaults to true might provide backwards compatibility.
I'm making these suggestions without looking at the Nodemon source or understanding the burden of implementing and maintaining these features so I understand if 'events aren't the right way' is still the answer, but I thought I would give my thoughts.
One thing to keep in mind though is that for my use case, I'm using the nodemon.json file to run scripts on certain events. I actually need something to be run, synchronously, after the node application has stopped but before it has started again. I would like to be able to use the nodemon.json file but if I have to write a small boot node script to run Nodemon, that would be acceptable to me.
Thanks for the tool. Nodemon is a great tool and if it wasn't for my particular use-case I would consider it perfect.
Another update: I was able to solve my use case by writing a wrapper that runs before my main Express application.
npm install --save-dev child-process-promisebin/www_prerun.js
var path = require("path");
var exec = require('child-process-promise').exec;
// local_modules/* is where our local modules live
// this updates them before each reboot so that developing a module is easier.
exec('npm install --force local_modules/*')
.then(function (result) {
var stdout = result.stdout;
var stderr = result.stderr;
console.log('stdout: ', stdout);
console.log('stderr: ', stderr);
require(path.join(__dirname, 'www'));
})
.fail(function (err) {
console.error('ERROR: ', err);
});
Then in the package.json I added a nodemon script that is run using npm run nodemon that runs the wrapper.
package.json
{
"scripts": {
"nodemon": "nodemon ./bin/www_prerun.js"
},
"devDependencies": {
"child-process-promise": "^1.0.1"
}
}
I would prefer a more built-in way of handling this case, but that's just my opinion. My problem is solved.
Using child-process-promise someone could chain a sequence of events like this.
bin/www_prerun.js
var path = require("path");
var exec = require('child-process-promise').exec;
exec('npm install --force local_modules/*')
.then(function (result) {
var stdout = result.stdout;
var stderr = result.stderr;
console.log('stdout: ', stdout);
console.log('stderr: ', stderr);
})
.then(function () {
return exec('another command');
})
.then(function (result) {
var stdout = result.stdout;
var stderr = result.stderr;
console.log('stdout: ', stdout);
console.log('stderr: ', stderr);
})
.then(function () {
require(path.join(__dirname, 'www'));
})
.fail(function (err) {
console.error('ERROR: ', err);
});
I support the middleware implementation that @remy suggested above.
I need this functionality for a different reason. I need to be able to hook the exit command for production reasons. Personally I would really like to see something like
gulp.task('launchserver', ['mocha'], function () {
nodemon({
script: 'app.js',
ext: 'js',
tasks: ['mocha'],
watch: ['./MyStuff/*_/_.js]
})
.on('restart', 'mocha')
.pre('exit', 'my-exit-gulp-task');
});
was any more done on this ? I'm getting an odd error where sometimes the nodemon restart seems to , well, restart (!) my express process before the original process has ended, so then I get an
Error: listen EADDRINUSE error
is there any way of making nodemon wait until the process has stopped before starting again ?
+1
I would love this feature too. What I'm looking for is a way to run npm install when package.json changes (but not on every restart, since npm install does take some time to execute).
+1
Anyone else just posts +1 I'll close this issue. I prefer PRs, then second best is constructive ideas on how to implement (which I believe we've been over a few times anyway). If you want to show interest in this issue, follow it, or use the github controls to add you support.
This issue has been automatically marked as idle and stale because it hasn't had any recent activity. It will be automtically closed if no further activity occurs. If you think this is wrong, or the problem still persists, just pop a reply in the comments and @remy will (try!) to follow up.
Thank you for contributing <3
Hi guys,
some time has passed and I was wondering if there is a suitable solution for this now?
Regards,
Tim
Any update?
@remy I would like to work on this feature. By adding pre-hooks or any other implementation which we can decide upon.
Most helpful comment
@remy I would like to work on this feature. By adding pre-hooks or any other implementation which we can decide upon.