13

I have a gulp.js file that includes:

gulp.task('default', ['watch']);

Which starts up the watch task

gulp.task('watch', function(){
  gulp.watch(productionScripts, ['autoConcat']);
});

Then on any saved changes to files in productionScripts, the watch task will concat the files.

What I would like to do, is in my package.json, I would like to spool up this watch when I type npm start (this already starts my node server).

package.json

    "start": "node server.js",

UPDATE--------

Ben(b3nj4m.com), I tried what you stated. The watch and server start up. However, everything runs twice (probably due to the editor, not related), but I do lose my server log when I start it up with gulp.

[15:31:18] Starting 'autoConcat'...
[15:31:18] Finished 'autoConcat' after 147 ms
[15:31:19] Starting 'autoConcat'...
[15:31:19] Finished 'autoConcat' after 138 ms
[15:31:20] Starting 'autoConcat'...
[15:31:20] Finished 'autoConcat' after 127 ms
[15:31:23] Starting 'autoConcat'...

It's like there is a loop between the server restarting on a change, and the concatenated file changing.

3
  • use gulp watch instead and tie starting and restarting your server into the gulp watch process, that way when you change code for your server, gulp will restart it.
    – Kevin B
    Commented Jan 19, 2015 at 17:12
  • instead of npm start you recommend gulp "myFunctionName" with the server starting in gulp? Do you have an example?
    – SoEzPz
    Commented Jan 19, 2015 at 17:13
  • I do not, i just know that it is definitely possible.
    – Kevin B
    Commented Jan 19, 2015 at 17:14

4 Answers 4

20

You could run your server from your gulpfile:

var child = require('child_process');
var fs = require('fs');

gulp.task('default', ['server', 'watch']);

gulp.task('server', function() {
  var server = child.spawn('node', ['server.js']);
  var log = fs.createWriteStream('server.log', {flags: 'a'});
  server.stdout.pipe(log);
  server.stderr.pipe(log);
});

gulp.task('watch', function(){
  gulp.watch(productionScripts, ['autoConcat']);
});

Then change your npm start definition to look like:

"scripts": {
  "start": "gulp"
}
2
  • you wouldn't happen to know how to get the server log back would you?
    – SoEzPz
    Commented Jan 22, 2015 at 15:20
  • child_process.spawn() returns a ChildProcess object, which has stdout, and stderr streams. You can pipe those streams somewhere, e.g. to a file. I will add an example to my answer.
    – Ben
    Commented Jan 22, 2015 at 15:28
11

You could concatenate multiple tasks in your start in package.json using the package concurrently as such:

{
  "start": "concurrent \"node server.js\" \"gulp\" "
}

And run npm start from your terminal. This would execute all statements within start.

For references: https://www.npmjs.com/package/concurrently

EDIT:

As pointed out by @Josh in the comments, the CLI name now matches the package name. Hence, you could write the script as:

{
   "start": "concurrently \"node server.js\" \"gulp\" "
}
6
  • 1
    Should not it be concurrently and not concurrent?
    – Omar Tariq
    Commented Sep 6, 2016 at 5:37
  • The package name is concurrently. The command used to execute the package is concurrent.
    – nashcheez
    Commented Sep 7, 2016 at 7:47
  • @nashcheez I did but on npm start the scss is not getting compiled to css as it should be. Here is the code in package.json: "start": "concurrently \"npm run tsc:w\" \"npm run lite\" \"gulp\" ",
    – Manu
    Commented Nov 4, 2016 at 17:59
  • @angular2 I am guessing there is an error with your gulp file code (for conversion of scss to css) rather than the command here.
    – nashcheez
    Commented Nov 9, 2016 at 6:55
  • 1
    @nashcheez This is no longer the case. The CLI name now matches the package name, ie concurrently. github.com/kimmobrunfeldt/concurrently/releases/tag/2.0.0 Commented Dec 25, 2017 at 19:09
7

I have something like this in one of my projects. Note that it will background both processes - you can use ps to get the ID and stop it with kill <pid>.

"scripts": {
    "start": "{ gulp watch & node server.js & }"
}

To disable logging, too:

"scripts": {
    "start": "{ gulp watch --silent & node server.js & }"
}
2
  • What's the second & for?
    – SoEzPz
    Commented Jan 19, 2015 at 21:36
  • Without it the command will fail with an ELIFECYCLE error; you need to background both tasks in the one command.
    – Ben
    Commented Jan 19, 2015 at 22:26
6

One best practice to consider is to use nodemon and gulp-nodemon and then like the accepted answer, trigger the gulp script from npm with npm start. It's blazing fast and you get the node server restarted on file changes. For example:

gulpfile.js

var gulp = require('gulp');
var nodemon = require('gulp-nodemon');

...

var nodemonOptions = {
    script: 'bin/www.js',
    ext: 'js',
    env: { 'NODE_ENV': 'development' },
    verbose: false,
    ignore: [],
    watch: ['bin/*', 'routes/*', 'app.js']
};

gulp.task('start', function () {
    nodemon(nodemonOptions)
        .on('restart', function () {
            console.log('restarted!')
        });
});

package.json

{
    ...

    "scripts": {
        "start": "gulp start"
    },
    "devDependencies": {
        "gulp": "^3.9.0",
        "gulp-nodemon": "^2.0.4"
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.