Last active
August 29, 2015 14:02
-
-
Save narirou/9f5ed528614dacb45459 to your computer and use it in GitHub Desktop.
a tiny gulp-plugin: automatically restart your server for development.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var _ = require( 'lodash' ), | |
gutil = require( 'gulp-util' ), | |
Transform = require( 'stream' ).Transform, | |
fork = require( 'child_process' ).fork; | |
function started( callback ) { | |
return function() { | |
gutil.log( 'development server listening. ( PID:', gutil.colors.magenta( app.child.pid ), ')' ); | |
if( callback ) callback(); | |
}; | |
} | |
function stopped( callback ) { | |
return function() { | |
gutil.log( 'development server was stopped. ( PID:', gutil.colors.magenta( app.child.pid ), ')' ); | |
app.child = null; | |
if( callback ) callback(); | |
}; | |
} | |
function restarted( callback ) { | |
return function( error ) { | |
if( ! error ) { | |
gutil.log( gutil.colors.cyan( 'development server was restarted.' ) ); | |
} | |
if( typeof callback === 'function' ) { | |
callback( error ); | |
} | |
}; | |
} | |
function app() { | |
var stream = new Transform({ objectMode: true }); | |
stream._transform = function( file, encoding, callback ) { | |
this.push( file ); | |
app.changed( callback ); | |
}; | |
stream.changed = app.changed; | |
return stream; | |
} | |
app.child = null; | |
app.defaultOptions = { | |
path: '', | |
env: { NODE_ENV: 'development' }, | |
nodeArgs: [], | |
delay: 600, | |
messages: { | |
listening: /server listening/, | |
} | |
}; | |
app.options = _.cloneDeep( app.defaultOptions ); | |
app.listen = function( options, callback ) { | |
// throw error when options is not set | |
if( ! app.options.path && typeof options.path !== 'string' ) { | |
throw new gutil.PluginError( 'gulp-develop-server', 'application `path` required.' ); | |
} | |
// fallback arguments | |
if( typeof options === 'function' ) { | |
callback = options; | |
options = {}; | |
} | |
// override default options | |
else if( typeof options === 'object' ) { | |
_.merge( app.options, options ); | |
} | |
// add Node's arguments | |
var args = app.options.nodeArgs; | |
if( args instanceof Array && args.length ) { | |
args.forEach( function( arg ){ | |
process.execArgv.push( arg ); | |
}); | |
} | |
// run server process | |
app.child = fork( app.options.path, { silent: true, env: app.options.env } ); | |
// run callback | |
// if not receive an error after `options.delay` seconds, | |
// regard the server listening success. | |
var timer = setTimeout( started( callback ), app.options.delay ); | |
// timer.unref(); | |
app.child.on( 'message', function( message ) { | |
if( timer && typeof message === 'string' && message.match( app.options.messages.listening ) ) { | |
clearTimeout( timer ); | |
started( callback )(); | |
} | |
}); | |
app.child.stderr.on( 'data', function( error ) { | |
gutil.log( gutil.colors.red( 'development server error:' ) ); | |
if( timer ) clearTimeout( timer ); | |
if( callback ) { | |
var errorMessage = '' + error || null; | |
callback( errorMessage ); | |
} | |
}); | |
// pipe child process's stdout / stderr | |
app.child.stdout.pipe( process.stdout ); | |
app.child.stderr.pipe( process.stderr ); | |
}; | |
app.kill = function( signal, callback ) { | |
// fallback arguments | |
if( typeof signal === 'function' ) { | |
callback = signal; | |
signal = 'SIGTERM'; | |
} | |
// sending kill signall | |
if( app.child && app.child.connected ) { | |
app.child.on( 'exit', stopped( callback ) ); | |
return app.child.kill( signal ); | |
} | |
// server already stopped | |
if( typeof callback === 'function' ) { | |
process.nextTick( callback ); | |
} | |
}; | |
app.changed = app.restart = function( callback ) { | |
app.kill( function() { | |
app.listen( restarted( callback ) ); | |
}); | |
}; | |
app.reset = function( callback ) { | |
app.kill( function() { | |
app.options = _.cloneDeep( app.defaultOptions ); | |
if( callback ) callback(); | |
}) | |
} | |
module.exports = app; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// example usage: | |
// automatically restart by gulp-develop-server. | |
// livereload by gulp-livereload. | |
'use strict'; | |
var gulp = require( 'gulp' ), | |
server = require( 'gulp-develop-server' ), | |
livereload = require( 'gulp-livereload' ); | |
var src = { | |
server: [ | |
'routes/**/*.js', | |
'models/**/*.js', | |
'libs/**/*.js', | |
'app.js', | |
], | |
resources: [ | |
'views/**/*.jade', | |
'public/scripts/**/*.js', | |
'public/images/**/*.{png,jpg,jpeg,gif,webp,svg}' | |
] | |
}; | |
gulp.task( 'server', function() { | |
server.listen( { path: 'app.js' }, livereload.listen ); | |
}); | |
gulp.task( 'watch', function() { | |
function restartServer() { | |
server.changed( function( error ) { | |
if( ! error ) livereload.changed(); | |
}); | |
} | |
gulp.watch( src.server, restartServer ); | |
gulp.watch( src.resources, livereload.changed ); | |
}); | |
gulp.task( 'default', [ 'server', 'watch' ] ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this project moved to:
https://github.com/narirou/gulp-develop-server