40

This is how can i run my server nodejs. I need to live reload my server when i make changes to the code in the front-end dev

"start": "node server.js"
Leos Literak
  • 8,805
  • 19
  • 81
  • 156
Rebai Ahmed
  • 1,509
  • 1
  • 14
  • 21
  • Browserreload and nodemon can be used for both of this – Arpit Solanki Aug 10 '17 at 19:34
  • 1
    How can i integrate them in my code , i need to modify the package.json file only or to add some code to the server ? – Rebai Ahmed Aug 10 '17 at 19:35
  • No need to add any code to the server. Just use nodemon to run your server – Arpit Solanki Aug 10 '17 at 19:36
  • nodemon looks like it's suited for backend (node server) development. for front-end you can use https://www.npmjs.com/package/livereload in combination with https://www.npmjs.com/package/watch-run – pawel Aug 10 '17 at 19:37

10 Answers10

29

first:

npm install -g nodemon

next add a script line to your package.json

"live": "nodemon server.js" 

now when you npm live it'll live reload

for more details see https://github.com/remy/nodemon

update if live page reload is also needed

npm install -g livereload
livereload . -w 1000 -d

for more details see https://github.com/napcs/node-livereload

Mark Essel
  • 4,606
  • 2
  • 29
  • 47
  • 40
    This doesn't live reload the browser, it just live reloads the server. You still need to manually refresh the page. – Daniel Apr 08 '18 at 03:52
  • this restarts the server not the browser – Angel S. Moreno May 01 '19 at 00:02
  • 8
    the question was " i need to liverealord my server" not live reload my browser – Mark Essel May 14 '19 at 20:00
  • 4
    A note from someone looking for true live-reload: this is not actually a _live_-reload for the server, this is an automatic restart, which is a very different thing. This solution kills the node process, and the starts a _new_ process that happens to run on the same port. If someone is logged into the server, or the server itself is authed for some external API, this solution will not offer you the live-reload you were looking for. – Mike 'Pomax' Kamermans Feb 09 '20 at 17:33
  • 2
    The asker mentioned his need for the front-end dev. The confusion seems legit for a beginner. – GBMan Mar 29 '20 at 12:07
  • @dspacejs your comment is now misleading as Mark updated with livereload. Furthermore, live reload for the browser is not asked as Mark says. – Timo Mar 06 '21 at 07:31
  • There seem to be 3 browser refreshers: livereload (described here), browser-sync (@alonad) and there is [live-server](https://stackoverflow.com/q/61250124/1705829). Probably my question here which is best deserves an own question. – Timo Mar 13 '21 at 18:26
17

Restarting server is one thing, refreshing browser is another thing. For server watching I use nodemon. Nodemon can see when changes occur in any types of files. But nodemon cannot refresh browser page. For this I use browser sync.

I use both in gulp.

So, dependencies from package.json to make it work:

"devDependencies": {
"browser-sync": "^2.24.5",
"gulp": "^3.9.1",
"gulp-nodemon": "^2.2.1"
}

In server file (my server is in ./bin/www, yours can be in server.js, app.js or elsewhere), express server listens to port 3001.

var port = normalizePort(process.env.PORT || '3001');
var server = http.createServer(app);
server.listen(port);

Next thing is to run nodemon and browser sync in gulp. Full contents of gulpfile.js

var gulp = require('gulp');
var nodemon = require('gulp-nodemon');
var browserSync = require('browser-sync').create();

gulp.task('gulp_nodemon', function() {
  nodemon({
    script: './bin/www', //this is where my express server is
    ext: 'js html css', //nodemon watches *.js, *.html and *.css files
    env: { 'NODE_ENV': 'development' }
  });
});

gulp.task('sync', function() {
  browserSync.init({
    port: 3002, //this can be any port, it will show our app
    proxy: 'http://localhost:3001/', //this is the port where express server works
    ui: { port: 3003 }, //UI, can be any port
    reloadDelay: 1000 //Important, otherwise syncing will not work
  });
  gulp.watch(['./**/*.js', './**/*.html', './**/*.css']).on("change", browserSync.reload);
});

gulp.task('default', ['gulp_nodemon', 'sync']);

When running gulp in terminal, it will start watching server as well as refreshing browser on change in any files.

Although we specify port 3001 in express server, our app will be working on port 3002, as we write in browser-sync. 3001 will be used as proxy.

themefield
  • 3,847
  • 30
  • 32
Alonad
  • 1,986
  • 19
  • 17
  • 2
    I can't seem to get this working in the latest gulp v4, authough it is working fine in gulp v3. Can you suggest what needs updating/changing? – Mike D Jul 05 '20 at 19:14
  • @MikeD For v4 and beyond, you need to change the last line to `gulp.task('default', gulp.series('gulp_nodemon', 'sync'));` – kohane15 Sep 16 '20 at 06:45
  • Does not work. Even though your comment says the app will be visible on port 3002, this is not the case. Running `gulp` on the terminal prints `listening on *:3001` and that is the only port where the app is accessible. Nodemon updates with files, but no browser refresh. – john Apr 08 '21 at 18:33
  • 2
    I've used the comments here to make a little boilerplate in case you want something that'll work from the get-go, code [here](https://github.com/dengel29/express-hot-reload). Bonus, it's sass-ready as well. It uses nodemon, gulp and browsersync, but updates for Gulp 4. Mostly same as code above with the exception of the last line: `exports.build = gulp.parallel(["gulp_nodemon", "sync"]);` Writing exports.build makes the `gulp build` command available in your npm scripts. – Dan Engel Jun 15 '21 at 02:39
11

You can livereload both front and backend changes to the browser with 'livereload', 'connect-livereload', and 'nodemon' packages. This way you don't need Gulp. Here's how the packages team up:

  • livereload opens a high port and notifies the browser of changed public files
  • connect-livereload monkey patches every served HTML page with a snippet that connects to this high port
  • nodemon restarts server on changed backend files

Set up livereload in Express

Set up Express to both start livereload server watching the public directory and ping the browser during nodemon-induced restart:

const livereload = require("livereload");
const connectLivereload = require("connect-livereload");

// open livereload high port and start to watch public directory for changes
const liveReloadServer = livereload.createServer();
liveReloadServer.watch(path.join(__dirname, 'public'));

// ping browser on Express boot, once browser has reconnected and handshaken
liveReloadServer.server.once("connection", () => {
  setTimeout(() => {
    liveReloadServer.refresh("/");
  }, 100);
});

const app = express();

// monkey patch every served HTML so they know of changes
app.use(connectLivereload());

Start Express with nodemon

Start the server with nodemon, for example, with a dedicated watch script npm run watch.

The key point here is to ignore the public directory that's already being watched by livereload. You can also configure files with non-default extensions, like pug and mustache, to be watched.

"scripts": {
  "start": "node ./bin/www",
  "watch": "nodemon --ext js,pug --ignore public"
},

You can read a longer explanation in "Refresh front and backend changes to browser with Express, LiveReload and Nodemon."

pspi
  • 11,189
  • 1
  • 20
  • 18
  • Hi, Thanks for your answer but... I get an error when using "path". > ReferenceError: path is not defined How LiveReload is started? – GBMan Mar 29 '20 at 12:50
  • @GBMan path is a Node core module, and you can require it with `const path = require("path")`. many times this is already included as app setup deals with paths – pspi Apr 02 '20 at 05:45
  • not working if you setup your server manually instead of express-generator like things.. – Muhammad Saquib Shaikh Jun 06 '20 at 22:53
  • @pspi is it possible to assign the same 3000 port to the live reload along with the node server? – K.Raj. Apr 05 '21 at 12:39
6
npm install browser-refresh -g

and add your main js

 if (process.send) {
     process.send('online');
 }

for example

app.listen(port, function() {
    console.log('Listening on port %d', port);

    if (process.send) {
        process.send('online');
    }
});

and add your index page before body close tag.

<script src="{process.env.BROWSER_REFRESH_URL}"></script>

and start your server on termial instead node server.js

browser-refresh server.js
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Murat Çimen
  • 465
  • 4
  • 8
  • 1
    browser-refresh is awesome. Works well. In case you're looking for a solution with SSR: https://medium.com/@gagan_goku/hot-reloading-a-react-app-with-ssr-eb216b5464f1 – Kira May 10 '19 at 04:54
  • [Doks](https://www.npmjs.com/package/browser-refresh) – Timo Mar 05 '21 at 20:05
4

An example from my setup:

livereload.js (so this would be your server.js, of course only use the parts related to livereload, no need to replace your development server)

const path = require('path');
const fs = require('fs');

const livereload = require('livereload');
const lrserver = livereload.createServer();

const compiled = path.join( __dirname, "dist");
lrserver.watch( compiled ); 

const connect = require('connect');
const stat = require('serve-static');

const server = connect();
server.use( stat( compiled ));

server.listen( 3033 );

console.log( 'Dev server on localhost:3033' );

It actually starts two servers on localhost: the livereload server listening on :35729 and a static file server on :3033.

Livereload observes the dist directory which contains the compiled files (js, css, html). You need to add this snippet to every HTML page that should reload:

<script>
 document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] +
                ':35729/livereload.js?snipver=1"></' + 'script>');
</script>

If you don't transpile/compile/preprocess your js/css/html code (i.e. you directly edit the files that are served) then observe the source directory and you're done. Otherwise you need a task that watches the source directory for changes and compiles to the dist directory which is observed by livereload :)

Relevant parts of my package.json:

"scripts": {
    "build": "npm run build:js && npm run build:css",
    "prewatch": "node livereload.js &",
    "watch": "node ./node_modules/watch-run/bin/watch -p './src/**' npm run build",
  },
"devDependencies": {
    "connect": "^3.6.2",
    "livereload": "^0.6.2",
    "serve-static": "^1.12.3",
    "watch-run": "^1.2.5"
  }

$ npm run watch builds the project and starts the livereload + static file servers. (the build:* tasks omitted for brevity).

pawel
  • 35,827
  • 7
  • 56
  • 53
2

With Node.js 19 you can monitor file changes with the --watch option. After a file is changed, the process is restarted automatically, reflecting new changes.

"start": "node --watch server.js"
1

Use the npm package called livereload.

Use it in conjunction with nodemon so both client side and server side work flawlessly.

npm install livereload nodemon --save

--save-dev. I know, I know!

Add browser extension. Available for Safari, Firefox, and Google Chrome. Get them here.

Make sure to have this scripts inside package.json.

  "scripts": {
"start": "nodemon server.js && livereload"

}

server.js is my entry point.

Inside the server.js add the following:

const livereload = require('livereload');
const reload = livereload.createServer();
reload.watch(__dirname + "/server.js");

server.js is the file I want livereload to watch. You can add any directory instead of a file as well.

reload.watch(__dirname + "/public");

In terminal: npm start

Click on the extension icon in the browser to connect.

You can also use livereload and nodemon separately in different terminals.

"scripts": {
    "start": "nodemon server.js",
    "livereload": "livereload"
  }

npm start

npm livereload

npm livereload -p PORT_NUMBER if default is port is already used.

Update: sometimes it doesn't work on saving once. A couple more of Ctrl+S reloads again and makes the changes. I don't know if this is a browser caching issue or package issue.

therj
  • 151
  • 1
  • 9
1

If grunt is used, there is a npm package grunt-contrib-watch for live reloading.

Check out another one called grunt-express-server that can work together.

themefield
  • 3,847
  • 30
  • 32
0

You can use nodemon.
It will watch your project's files and restarts the server when you change them.

You can install it globally:

npm install -g nodemon

the run it on your projects directory

cd ./my-project
nodemon

You can also add it to your project's dev dependencies and use it from an npm script:

npm install --save-dev nodemon

Then add a simple script to your package.json:

"scripts": {
    "start": "node server.js",
    "dev": "nodemon"
}

then you can simply run the following command:

npm run dev
Kayvan Mazaheri
  • 2,447
  • 25
  • 40
0

A really really simple way to have the browser reload on changes is to use the react-dev-utils package (https://github.com/facebook/create-react-app/blob/main/packages/react-dev-utils/openBrowser.js)

  1. Use something like nodemon to rebuild your server.
  2. invoke the react-dev-utils in your express server listener callback:
import openBrowser from "react-dev-utils/openBrowser";
import express from "express";

const app = express();
app.get("/foo", (req, res) => res.send("hello: " + new Date().toISOString()));

app.listen(3000, () => {
  console.debug(`Running on http://localhost:3000`);
  
  // this will open a new browser tab  or reload the open one
  openBrowser(`http://localhost:3000`);
});

paulrostorp
  • 35
  • 1
  • 9