Instantly share code, notes, and snippets.

@sogko /app.js
Last active Dec 4, 2018

Embed
What would you like to do?
gulp + expressjs + nodemon + browser-sync
'use strict';
// simple express server
var express = require('express');
var app = express();
var router = express.Router();
app.use(express.static('public'));
app.get('/', function(req, res) {
res.sendfile('./public/index.html');
});
app.listen(5000);
'use strict';
var gulp = require('gulp');
var browserSync = require('browser-sync');
var nodemon = require('gulp-nodemon');
gulp.task('default', ['browser-sync'], function () {
});
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(null, {
proxy: "http://localhost:5000",
files: ["public/**/*.*"],
browser: "google chrome",
port: 7000,
});
});
gulp.task('nodemon', function (cb) {
var started = false;
return nodemon({
script: 'app.js'
}).on('start', function () {
// to avoid nodemon being started multiple times
// thanks @matthisk
if (!started) {
cb();
started = true;
}
});
});
<html>
<head>
<link rel="stylesheet" href="site.css"/>
</head>
<body>
<!-- some dummy non-conforming quick dirty html code to test browser-sync. dont't judge me. -->
<b>lorem</b> ipsum upsum dumsum
</body>
</html>
<!-- put this under /public/* -->
{
"name": "gulp-expressjs-nodemon-browser-sync",
"version": "0.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": {
"name": "Hafiz Ismail",
"email": "hafiz@wehavefaces.net",
"url": "http://wehavefaces.net"
},
"license": "ISC",
"dependencies": {
"express": "^4.8.2"
},
"devDependencies": {
"browser-sync": "^1.3.3",
"gulp": "^3.8.7",
"gulp-nodemon": "^1.0.4"
}
}
/* some css */
/* put this under /public/* */
body {
font-family: 'Helvetica';
color: red;
font-size:24px;
}
@sogko

This comment has been minimized.

Owner

sogko commented Aug 10, 2014

Description:
Full working example of using gulp + browser-sync + nodemon to serve an expressJS app.

Quick start:

  • Put index.html and site.css under public/ folder. (Gists don't allow folders, I should move this to a github repo sometime later)
  • Install node depencencies: npm install
  • Start gulp
  • Profit

Notes:

  • When running gulp, I'd get the following error: [BS] [ERROR] Proxy address not reachable. Is your server running?.
    Seems harmless. But created an issue at BrowserSync/gulp-browser-sync#25
@sogko

This comment has been minimized.

Owner

sogko commented Aug 11, 2014

For those interested, I'm starting a repo of gulp-recipes, including this one

Take a look at https://github.com/sogko/gulp-recipes

@rbg246

This comment has been minimized.

rbg246 commented Oct 1, 2014

Thanks this worked really well.

@lindekaer

This comment has been minimized.

lindekaer commented Mar 12, 2015

Looks great - however, I do not quite understand the role of 'cb()' in nodemon.
Why is it called?
What does the call do?

@adam-beck

This comment has been minimized.

adam-beck commented Mar 20, 2015

@lindekaer the reason behind the callback is so that the browser-sync task does not start before nodemon one is complete. The callback is internal to gulp and by using it you can signal that the task is truly complete. Another way of doing this (which you might also see elsewhere) is just returning the stream.

For more (and probably better) information check out this gulp recipe.

However, there seems to be a problem with this gist. The callback would be called multiple times and that would lead to an error (as the callback can only be called once per task). A better way would be to set a flag that makes sure it is called when the server is started for the first time only.

Also, I noticed this gist is returning the nodemon stream and using a callback. When I removed the callback the nodemon task never finished leaving me to believe that gulp-nodemon does not return a stream. I haven't gone through the code but normally that works identical to using callback.

Fun Fact: callback used 7 times in this comment

@ArayZou

This comment has been minimized.

ArayZou commented Mar 25, 2015

Thanks,it's very good

@andreasmaier

This comment has been minimized.

andreasmaier commented Apr 25, 2015

@adam-beck Thanks for your reply, the 'callback called multiple times' error was driving me crazy. The flag solution worked for me.

@importjake

This comment has been minimized.

importjake commented May 8, 2015

@andreasmaier @adam-beck what would need to be changed exactly in this current gist to prevent the callback from being fired multiple times?

@matthisk

This comment has been minimized.

matthisk commented May 20, 2015

@schmittyjd the callback function is basically the task function for the browser-sync task. We ask gulp to execute the nodemon task before executing the body of the browser-sync task. The callback ensures that the task function of browser-sync is called after the express server is started. Now here is where the error comes in, because nodemon is going to reload every time app.js is changed the callback function is called multiple times while gulp expects the function only to be called once (after the nodemon task has been setup). If you add something like if(init) cb(); init = false; instead of just calling the callback function you fix this problem (don't forget to initialize the init var to true in the start of the task).

@ponelat

This comment has been minimized.

ponelat commented Jun 30, 2015

FWIW nodemon is an EventEmitter, so for a clean solution just use...

gulp.task('nodemon', function (cb) {
    return nodemon({
      script: 'app.js'
    }).once('start', cb); // once only get's run........... <drum role>........ once :D
});
@minwe

This comment has been minimized.

minwe commented Jul 2, 2015

@ponelat I try to use once, then browserSync will not work when nodemon restarting, any idea?

@sogko

This comment has been minimized.

Owner

sogko commented Jul 3, 2015

Hi guys, i've added the fixed suggested by @adam-beck and @matthisk.

Let the rest know if this solves the issue with nodemon being called multiple times. Or if more bugs started popping up.

@gocreating

This comment has been minimized.

gocreating commented Jul 5, 2015

awesome!
my nodemon won't show lots of errors anymore 😄

@aethant

This comment has been minimized.

aethant commented Jul 14, 2015

Hey, I'm trying to get this to work in addition to using Webpack to chunk my code.

I'm having it watch the folder where webpack puts my compiled bundles, and BrowserSync sees the files changing, but the reload doesn't happen.

I'm also noticing that the typical BS code isn't being injected into the page. Will this gist only work with a static served html file? In theory, I could make that happen. Thoughts?

@rossthedevigner

This comment has been minimized.

rossthedevigner commented Aug 4, 2015

Has anyone experienced an issue where you see two express app requests fire? It seems to be one for the page, then one for when BrowserSync loads? Edit: favicon.ico. For some reason or another this was only happening in Chrome and not FF.

@cognizen

This comment has been minimized.

cognizen commented Oct 24, 2015

Thanks - this tut was exactly what I was looking for to get me rolling!

@ivorscott

This comment has been minimized.

ivorscott commented Dec 3, 2015

Bless!

@sefel

This comment has been minimized.

sefel commented Jan 26, 2016

Thx. I was looking for something like this!

@MacgyverMartins

This comment has been minimized.

MacgyverMartins commented Feb 27, 2016

Thanks man. This help me a lot!

@rakeshongithub

This comment has been minimized.

rakeshongithub commented Mar 25, 2016

very helpfull

@emveeoh

This comment has been minimized.

emveeoh commented Apr 3, 2016

Thank you!

@tomekrozalski

This comment has been minimized.

tomekrozalski commented Apr 19, 2016

Holy moly, works fantastic! 👯

@ohsiwon

This comment has been minimized.

ohsiwon commented May 13, 2016

This is great! Thank you!

@jcloutz

This comment has been minimized.

jcloutz commented May 25, 2016

This i awesome, thank you for posting!

@gcfabri

This comment has been minimized.

gcfabri commented Jun 23, 2016

Thank you, very helpful!

@buffaloo

This comment has been minimized.

buffaloo commented Jul 13, 2016

great gulp-recipe.

@AlbertoFdzM

This comment has been minimized.

AlbertoFdzM commented Jul 27, 2016

Just as info if you change the package nodemon for gulp-nodemon you'll get the nodemon log traces too in the console. worth it.

@akhileshmohan

This comment has been minimized.

akhileshmohan commented Aug 3, 2016

Very useful conversation..thank you all

@github-polymer-user

This comment has been minimized.

github-polymer-user commented Aug 11, 2016

man it works, now I'm able to simulate production server with express (and kills every ugly fat bug in a wheels)

@eldyvoon

This comment has been minimized.

eldyvoon commented Aug 29, 2016

I got a forever loading, any clue why?

@deepank411

This comment has been minimized.

deepank411 commented Sep 10, 2016

Hi

This link has a part of my projects gulpfile: http://hastebin.com/iwocigizaq.coffee
I tried your code snippet to integrate browsersync with nodemon but all it leads to is an infinite load. No code(html/js/css) is loaded.
I have tried putting the port and the browser but to a no different result. I also unsuccessfully tried the code from https://github.com/sogko/gulp-recipes/blob/master/browser-sync-nodemon-expressjs/gulpfile.js .
Also my terminal log shows the nodemon is running with no error.

Can you please have a look at the gulp task and let me know if I'm doing something incorrectly.

Thanks

@zootella

This comment has been minimized.

zootella commented Oct 5, 2016

this is awesome. thanks.

@garrettmac

This comment has been minimized.

garrettmac commented Nov 7, 2016

This is great. I used it to make a my grabs a projects 'dist' folder and move it into the 'public' folder https://gist.github.com/garrettmac/07b475ad1043ad9c79a49ee61963e497

@IanGrainger

This comment has been minimized.

IanGrainger commented Nov 11, 2016

Great! I noticed my pages got out of date when I changed something that caused nodemon to restart, so I added:
nodemon.on...
.on('restart', function() {
browserSync.reload();
});

... Except it doesn't work because it calls the reload before the server has finished running up. Darn.

@sainthkh

This comment has been minimized.

sainthkh commented Dec 9, 2016

According to API, var browserSync = require('browser-sync'); is changed to var browserSync = require('browser-sync').create(); in 2.0.

@sainthkh

This comment has been minimized.

sainthkh commented Dec 9, 2016

For those who cannot run google chrome in windows:

Internally, browser-sync uses opn library. So, the name of browser is different from OS to OS. As for windows, it's not google chrome, it's just chrome. Other browsers:

  • Internet Explorer: iexplore
  • Firefox: firefox
  • Microsoft Edge: path.join(__dirname, ".bin", "edge.exe")

As Microsoft Edge doesn't have the way to call it by cmd start "some command for edge", so we need special command line program. I've downloaded it to projectRoot/.bin and changed its name to "edge.exe". So, the name of edge is really odd. However, when every setup is done, everything works nicely.

@coverboy

This comment has been minimized.

coverboy commented Mar 4, 2017

Pretty Awesome!! Thanks.

@omadoyeabraham

This comment has been minimized.

omadoyeabraham commented Mar 31, 2017

For those who have the "loading forever" issue, I had to install nodemon, and then run nodemon in a separate terminal for the gulp task to load. Don't know exactly why though.

@ChingizMizambekov

This comment has been minimized.

ChingizMizambekov commented Apr 15, 2017

Nice job, thx!

@dkutelov

This comment has been minimized.

dkutelov commented May 24, 2017

Works great! Thx!

@cooljl31

This comment has been minimized.

cooljl31 commented Jun 13, 2017

Works great! Thx!

@sofakeer

This comment has been minimized.

sofakeer commented Jun 20, 2017

Works great! Thx!

@david1542

This comment has been minimized.

david1542 commented Nov 24, 2017

Does someone knows how to change the default behaviour of browser-sync which automatically delivers index.html as the root directory?
I tried changing that behaviour by simply defining a route inside my app.js but somehow it gets ignored.

@binler

This comment has been minimized.

binler commented Mar 7, 2018

Nice job, but i have a question?
It's just working when i access http://localhost:3000, when I access http://localhost:3000/users it not working, help me?

@danielchikaka

This comment has been minimized.

danielchikaka commented Aug 28, 2018

Looks promising but it breaks after running for the first time with this error:

`
Error: listen EADDRINUSE :::5000

at Object._errnoException (util.js:1022:11)

at _exceptionWithHostPort (util.js:1044:20)

at Server.setupListenHandle [as _listen2] (net.js:1351:14)

at listenInCluster (net.js:1392:12)

at Server.listen (net.js:1476:7)

at Function.listen (C:\xampp\htdocs\ndondo\aug2018\jobBoard\node_modules\express\lib\application.js:618:24)

at Object.<anonymous> (C:\xampp\htdocs\ndondo\aug2018\jobBoard\index.js:36:5)

at Module._compile (module.js:643:30)

at Object.Module._extensions..js (module.js:654:10)

at Module.load (module.js:556:32)

[18:01:36] [nodemon] app crashed - waiting for file changes before starting
`

Any ideas why ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment