gimm / gulp-express

gulp plugin for express
56 stars 26 forks source link

Error using Express generator #26

Closed hydrotik closed 9 years ago

hydrotik commented 9 years ago

I am getting an error when trying to use this with an express generator created project. I've tried multiple options but it seems to be centered around this line:

server.run(['DEBUG=dsgstyleguide:* ./bin/www']);

I've also taken out the args, etc. and it still doesn't seem to work. maybe i need to cwd first? didn't see an example of that in the closed ticket either. https://github.com/gimm/gulp-express/issues/23

in gulpfile I have:

var gulp = require('gulp');
var server = require('gulp-express');

gulp.task('server', function () {
    // Start the server at the beginning of the task 
    server.run(['DEBUG=dsgstyleguide:* ./bin/www']);

    // Restart the server when file changes 
    gulp.watch(['views/**/*.hbs'], server.notify);
    gulp.watch(['scss/**/*.scss'], ['styles:scss']);
    //gulp.watch(['{.tmp,app}/styles/**/*.css'], ['styles:css', server.notify]); 
    //Event object won't pass down to gulp.watch's callback if there's more than one of them. 
    //So the correct way to use server.notify is as following: 
    gulp.watch(['{.tmp,app}/public/stylesheets/**/*.css'], function(event){
        gulp.run('styles:css');
        server.notify(event);
        //pipe support is added for server.notify since v0.1.5,  
        //see https://github.com/gimm/gulp-express#servernotifyevent 
    });

    gulp.watch(['public/scripts/**/*.js'], ['jshint']);
    gulp.watch(['public/images/**/*'], server.notify);
    gulp.watch(['app.js', 'routes/**/*.js'], [server.run]);
});

And in my app.js I have:

// ...More code above
var routes = require('./routes/index');
var users = require('./routes/users');

var app = module.exports.app = exports.app = express();
app.use(require('connect-livereload')());

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
// More code below...

also wasn't sure if you could pass npm start in server.run. Thanks for the help!

gimm commented 9 years ago

this server.run takes two parameters(args and options), and it uses child_process.spawn in the back-end. args and options you provide are passed to child_process.spawn directly. I'm not pretty sure how to set the cwd options, but I think you should refer child_process.spawn's options for the details, to see how to set cwd the way you want. Currently, you used ['DEBUG=dsgstyleguide:* ./bin/www'] as the args, it's like to exec:

node DEBUG=dsgstyleguide:* ./bin/www

it won't work for sure. This args should at least contain the script file, e.g. ['app.js']

hydrotik commented 9 years ago

Thanks for the info

server.run(['./bin/www'], ['DEBUG=dsgstyleguide:* ']);

Worked in the browser and I see in the console:

[10:45:00] Using gulpfile ~/Desktop/Node/dsgstyleguide/gulpfile.js
[10:45:00] Starting 'server'...
[10:45:00] Finished 'server' after 21 ms

I see http requests being output, however when I make a change to the hbs files, I don't see any restart in the console or the browser. I have:

gulp.watch(['views/**/*.hbs'], server.notify);

in my gulp file

hydrotik commented 9 years ago

Seems the only missing component to this is the live reload which still doesn't seem to be firing:

I currently have:

var gulp = require('gulp'),
server = require('gulp-express'),
compass = require('gulp-compass'),
path = require('path'),
clean = require('gulp-clean'),
jshint = require('gulp-jshint');

gulp.task('server', function () {
    // Start the server at the beginning of the task 
    server.run(['./bin/www'], ['DEBUG=dsgstyleguide:*']);

    // Restart the server when file changes 
    gulp.watch(['./views/**/*.hbs'], function(event){
        console.log('hbs changed');
        server.notify(event);
    });

    gulp.watch(['scss/**/*.scss'], ['sass']);
    //gulp.watch(['{.tmp,app}/styles/**/*.css'], ['styles:css', server.notify]); 
    //Event object won't pass down to gulp.watch's callback if there's more than one of them. 
    //So the correct way to use server.notify is as following: 
    gulp.watch(['{.tmp,app}/public/stylesheets/**/*.css'], function(event){
        //gulp.run('styles:css');
        console.log('css changed');
        server.notify(event);
        //pipe support is added for server.notify since v0.1.5,  
        //see https://github.com/gimm/gulp-express#servernotifyevent 
    });
    gulp.watch(['./public/javascripts/**/*.js'], ['jshint']);
    gulp.watch(['./public/images/**/*'], function(event){
        console.log('image changed');
        server.notify(event);
    });
    gulp.watch(['./app.js', './routes/**/*.js'], [server.run]);
});

gulp.task('del', function() {
  return gulp
    .src(['./public/stylesheets/*.map', './public/stylesheets/*.css'])
    .pipe(clean());
});

gulp.task('sass', ['del'], function() {
  return gulp.src('./scss/**/*.scss')
    .pipe(compass({
      config_file: path.join(process.cwd(), 'config.rb'),
      project: path.join(process.cwd(), '/'),
      css: 'public/stylesheets',
      sass: 'scss',
      import_path: './',
      style: 'nested' //nested, expanded, compact, or compressed.
    }))
    .on('end', function() {
      console.log('compass');
    });
});

gulp.task('default', ['server'], function() {

});
hydrotik commented 9 years ago

also seeing the error in the console: Failed to load resource: Could not connect to the server. http://127.0.0.1:35729/livereload.js?snipver=1

gimm commented 9 years ago

did you have the following line in your app.js?

app.use(require('connect-livereload')());

or is http://127.0.0.1:35729/livereload.js?snipver=1 accessable in your browser?

btw, the second parameter for server.run is an object with key value pairs, so instead of server.run(['./bin/www'], ['DEBUG=dsgstyleguide:*']);, you need server.run(['./bin/www'], {DEBUG:'dsgstyleguide:*'});

hydrotik commented 9 years ago

In my app.js I have:

app.use(express.static(path.join(__dirname, 'public')));

app.use(require('connect-livereload')());

app.use('/', routes);
app.use('/users', users);

In Chrome I get the error:

GET http://127.0.0.1:3002/livereload.js?snipver=1 net::ERR_CONNECTION_REFUSED

To your second point, when I put in the value in the options object, I get the error:

Service process exited with [code => 1 | sig => undefined]

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: spawn ENOENT
    at errnoException (child_process.js:1001:11)
    at Process.ChildProcess._handle.onexit (child_process.js:792:34)
lm3000023484:dsgstyleguide dadams$ 

I took it out:server.run(['./bin/www'], []); and it is working fine without it. If I put in: server.run(['./bin/www'], {}); or server.run(['./bin/www']); I get the error below which seems odd.

Service process exited with [code => 1 | sig => undefined]

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: spawn ENOENT
    at errnoException (child_process.js:1001:11)
    at Process.ChildProcess._handle.onexit (child_process.js:792:34)
lm3000023484:dsgstyleguide dadams$ 
gimm commented 9 years ago

you need to put livereload before the static files:

app.use(require('connect-livereload')());
app.use(express.static(path.join(__dirname, 'public')));//static should after livereload

and for the spawn ENOENT, issue#27 is for this. I was curious, what's the content of ./bin/www

hydrotik commented 9 years ago

I moved it in front of the static line and still no luck. I see when I change the files that this is outputting to the console:

  tinylr:server param files +1.9m { files: [ '../../views/index.hbs' ] } undefined undefined [ '../../views/index.hbs' ]
  tinylr:server Changed event (Files: ../../views/index.hbs) +2ms

But I'm still getting the http error to the [Error] Failed to load resource: Could not connect to the server. (livereload.js, line 0)

My www file is just express generated boilerplate which has the following:

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('dsgstyleguide:server');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
gimm commented 9 years ago

@hydrotik I have a brand new project generated with express-generator, and this is what I've done to make the livereload work: https://github.com/gimm/gulp-express-sample/commit/9001e7890aa35dd667c25597e384e909f0dda9fe

basically, add one line in app.js

And for the spawn ENOENT, I'll continue to figure it out in issue#27

hydrotik commented 9 years ago

Thank you for the help again. I sent you an email with my project. Thought it might be easier. I did try what you did in the gists and it still didn't work.

gimm commented 9 years ago

@hydrotik I think I can give you the fix finally :) In uistyleguide, change app.js in this way:

//app.use(require('node-compass')({mode: 'expanded'}));//remove node-compass
app.use(require('connect-livereload')());//add connect-livereload before static serving
app.use(express.static(path.join(__dirname, 'public')));

the spawn ENOENT is caused by node-compass somehow, you can verify this by runing node bin/www or node app.js(you need to add app.listen in app.js though), and refresh your broswer, you will see this spawn error, so it shouldn't be introduced by gulp-express.

hydrotik commented 9 years ago

Yeah that didn't seem to work :/ You were able to get the project working with that fix?

gimm commented 9 years ago

yes, with that fix, I can get the app running, with live reload.

hydrotik commented 9 years ago

Ok I'm going to do some experimenting and see if someone else can run this too. Possible this is something with my machine...

gimm commented 9 years ago

just verified again, exactly two changes on your zip:

//gulpfile.js, line 10
server.run(['./bin/www']);//remove the second parameter []
//app.js, line 26
//app.use(require('node-compass')({mode: 'expanded'})); //comment out node-compass

works for me, double checked!

hydrotik commented 9 years ago

Really odd. Could not get it to work. In the end I ended up having to do this.

var gulp = require('gulp'),
server = require('gulp-express'),
compass = require('gulp-compass'),
path = require('path'),
clean = require('gulp-clean'),
jshint = require('gulp-jshint'),
livereload = require('gulp-livereload');

gulp.task('server', function () {
    // Start the server at the beginning of the task 
    server.run(['./bin/www'], []);

    livereload.listen();

    // Restart the server when file changes 
    gulp.watch(['./views/**/*.hbs'], function(event){
      console.log('hbs changed - do livereload');
      livereload.reload();
    });

    gulp.watch(['scss/**/*.scss'], ['sass']);

    gulp.watch(['./public/stylesheets/**/*.css'], function(event){
        console.log('css changed - do livereload');
        livereload.reload();
    });
    gulp.watch(['./public/javascripts/**/*.js'], ['jshint']);
    gulp.watch(['./public/images/**/*'], function(event){
        console.log('image changed - do livereload');
        livereload.reload();
    });
    gulp.watch(['./app.js', './routes/**/*.js'], function(event){
      server.run(['./bin/www'], []);
    });
});

gulp.task('sass', function() {
  return gulp.src('./scss/**/*.scss')
    .pipe(compass({
      config_file: path.join(process.cwd(), 'config.rb'),
      project: path.join(process.cwd(), '/'),
      css: 'public/stylesheets',
      sass: 'scss',
      import_path: './',
      style: 'nested' //nested, expanded, compact, or compressed.
    }))
    .on('end', function() {
      console.log('compass compiled');
    });
});

gulp.task('default', ['server'], function() {

});

I can close if you want, or if you want me to help you look further into this?

gimm commented 9 years ago

@hydrotik, we can call it off for now, as it's Chinese New Year now, I won't have too much time on this. Don't want to drag you down on this. Thanks for your patience :)

hydrotik commented 9 years ago

Happy New Year and no rush. Thank you for your help and let me know when you have some updates I can look at. Hopefully I gave you enough info in the meantime. Cheers!