• Stars
    star
    110
  • Rank 316,770 (Top 7 %)
  • Language
    JavaScript
  • Created over 10 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Node.js module to enable server restart and browser refresh in response to file modifications

browser-refresh

This module improves productivity by enabling instant web page refreshes anytime a front-end resource is modified on the server. This module supports live reloading of CSS and JavaScript without doing a full page refresh. This module utilizes the very efficient chokidar module for watching for changes to the file system. Web sockets are used to communicate with the browser. Minimal application code changes are required to benefit from this module.

Overview

Like nodemon, this module provides a drop-in replacement for the node command.

Compared to nodemon, the browser-refresh module has the following benefits:

  • It starts as a web sockets server and provides a web sockets client
  • It sets an environment variable for the spawned child process to let it know that it was launched using browser-refresh
  • Instead of configuring which directories/files to watch, you instead configure which directories/files to not watch using an optional .browser-refresh-ignore file (same format as .gitignore and .npmignore).
  • There is an optional taglib for Marko and Dust that injects the browser-refresh client if the application was launched using browser-refresh. Please see: browser-refresh-taglib
  • The browser-refresh process waits for the child process to tell it that it is ready to start serving traffic so that the web browser page is not refreshed too soon. This is done by the child process using process.send('online')

File patterns to ignore are automatically loaded from the first file that exists in the following list:

  1. .browser-refresh-ignore file in the current working directory
  2. .gitignore file in the current working directory

If no ignore file is found then the following ignore file patterns are used:

node_modules/
static/
.cache/
.*
*.marko.js
*.dust.js
*.coffee.js

NOTE:

Patterns to ignore files with a directory should have / at the end. For example, to ignore node_modules directory use node_modules/.

Installation

First, install the global command line interface for the browser-refresh module:

npm install browser-refresh -g

Add the following code snippet to the appropriate location based on when your application is ready to start serving traffic:

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');
    }
});

Alternatively, pass an object that specifies a url for browser-refresh to launch the first time your app starts:

if (process.send) {
    process.send({ event:'online', url:'http://localhost:8080/' });
}

Finally, add the following script to your page(s). Just before the closing </body> tag is a good place.

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

When browser-refresh launches your app a new BROWSER_REFRESH_URL environment variable is added with the URL that should be used to include the client-side script. The value of BROWSER_REFRESH_URL will be similar to http://localhost:12345/browser-refresh.js (the port is random). You should use whatever means your templating language or UI library provides to add the script to your page(s).

If you're using Marko, checkout browser-refresh-taglib which allows you to simply drop the following tag into your template instead of using the above <script> tag:

<browser-refresh/>

Configuration

Some of the features of the browser-refresh module can be configured by creating a .browser-refresh JSON configuration file at the root of your project.

SSL Support

To enable SSL support you must provide values sslCert and sslKey in your .browser-refresh configuration file.

  • sslCert: The path to a SSL certificate
  • sslKey: The path to a SSL key

Example:

{
    "sslCert": "server.crt",
    "sslKey": "server.key"
}

Server-side Refresh Delay

browser-refresh by default will refresh the active tab after 1500ms when your Node.js server gets reloaded. In case if you're server is taking longer time, You can optionally disable the delay property by setting delay to false in the .browser-refresh config json.

Example:

{
    "delay": false 
}

Or e.g. 3000 milliseconds

{
    "delay": 3000
}

Note: After the server restart, the active page will get reloaded as long as you trigger the online event on process.send

Example:

app.listen(port, () => {
    process.send && process.send('online'); // Process is a child process of browser-refresh
});

Open up WebPage on Server Startup

You can open up a webpage on server startup by passing a url property to process.send

Example:

app.listen(port, () => {
    process.send && process.send({ 
        event: 'online', 
        url: 'http://localhost:8080/' 
    });
});

Usage

Once you have installed browser-refresh using the directions provided above, you can then start your application as normal, except replace node with browser-refresh. For example:

# Old: node server.js
# New:
browser-refresh server.js

If the main property is configured correctly in your application's package.json then you can simply start your application using the following command:

browser-refresh

The browser-refresh command will pass all command line arguments to the child process. Therefore, you can pass any number of arguments to your application:

browser-refresh server.js --foo --bar

After launching your application using the browser-refresh command, you can then load any web page as normal. If the <browser-refresh> tag (or {@browser-refresh/} helper) were used then any time a resoure is modified then the application will be restarted and, then, when the server is ready a message will be sent to all of the connected browsers via a web socket connection to trigger a reload of the same web page.

Controlling Reloading

By default, this module does not try to be clever when handling a file modification. That is, by default, a full server restart and a full web page refresh are used whenever any type of file is modified on the server. This ensures that the server state and the client-side page state will always be correct and avoids frustrating edge cases. However, the browser-refresh module allows for modules to register "special reload" handlers that can short-circuit a full server restart. To disable a full server restart for a particular file pattern, the child process needs to send a message to the browser-refresh launcher process using the browser-refresh-client module.

For example, to enable special reloading, the following code can be used:

require('browser-refresh-client')
    .enableSpecialReload('*.foo *.bar')
    .onFileModified(function(path) {
        // Handle the modification of either a *.foo file or
        // a *.bar file...
    });

Both the marko and lasso modules provide support for enabling special reload handlers when using the browser-refresh module. Example usage:

require('marko/browser-refresh').enable();
require('lasso/browser-refresh').enable('*.marko *.css *.less *.styl *.scss *.sass *.png *.jpeg *.jpg *.gif *.webp *.svg');

To add your own special reload handlers for the browser-refresh module, please use the following code as a guide:

Refreshing CSS and Images

For improved developer productivity, this module supports refreshing of CSS and images without doing a full page refresh (similar to LiveReload). This is an opt-in feature that can be enabled using code similar to the following:

var patterns = '*.css *.less *.styl *.scss *.sass *.png *.jpeg *.jpg *.gif *.webp *.svg';

require('browser-refresh-client')
    .enableSpecialReload(patterns, { autoRefresh: false })
    .onFileModified(function(path) {
        // Code to handle the file modification goes here.

        // Now trigger a refresh when we are ready:
        if (isImage(path)) {
            browserRefreshClient.refreshImages();
        } else if (isStyle(path)) {
            browserRefreshClient.refreshStyles();
        } else {
            browserRefreshClient.refreshPage();
        }
    });

If you are using require('lasso/browser-refresh').enable(patterns), it is doing this for you automatically. Please see: lasso/browser-refresh/index.js

Passing arguments to node

Any flags (arguments that start with -) before the script path will be passed to the node executable:

browser-refresh --debug index.js

To use Typescript, you will need to require the ts-node register:

browser-refresh --require ts-node/register ./index.ts

Maintainers

Contribute

Pull requests, bug reports and feature requests welcome.

License

ISC

More Repositories

1

morphdom

Fast and lightweight DOM diffing/patching (no virtual DOM needed)
JavaScript
3,165
star
2

app-module-path-node

Simple module to add additional directories to the Node module search for top-level app modules
JavaScript
411
star
3

child-process-promise

Simple wrapper around the "child_process" module that makes use of promises
JavaScript
250
star
4

marko-vs-react

DEPRECATED - Test app to benchmark and compare Marko and React
HTML
90
star
5

warp10

Transport complex/circular JavaScript objects from the server to the web browser at lightning fast speeds
JavaScript
46
star
6

codemirror-atom-modes

Use Atom grammar files to apply syntax highlighting in a CodeMirror editor
JavaScript
16
star
7

warmup

Warmup server apps by hitting URLs or performing tasks.
JavaScript
12
star
8

require-self-ref

Solves the relative path problem in Node.js by allowing the target module argument of a require call to be relative to the root directory of the containing package
JavaScript
11
star
9

meta-router

Declarative URL router for Express that provides support for associating metadata with a route.
JavaScript
11
star
10

http-stats

Node.js module for benchmarking HTTP servers
JavaScript
7
star
11

listener-tracker

Allows added event listeners to be tracked for easy removal
JavaScript
7
star
12

express-view-streaming

Sample app that demonstrates streaming template rendering with Express
JavaScript
7
star
13

argly

A flexible command line arguments parser that is easy to configure and offers robust type handling.
JavaScript
7
star
14

async-config

A simple Node.js module for loading environment-specific config files.
JavaScript
6
star
15

express-resetter

Utility module to reset an Express instance to a previous state after registering middleware
JavaScript
6
star
16

browser-refresh-taglib

Taglib to enable browser page refresh in response to file modifications on the server
JavaScript
4
star
17

ignoring-watcher

Watch an entire directory tree while ignoring specific directories/files based on .gitignore rules.
JavaScript
4
star
18

browser-refresh-client

Small module to interface with the parent browser-refresh process to control reloading
JavaScript
3
star
19

events-light

Lightweight and fast implementation of the 'events' module for the browser and server
JavaScript
3
star
20

github-project-inspector

Node.js module that uses the Github API to gather metadata about a project on Github
JavaScript
2
star
21

velociblog

A static blog generator built on top of JavaScript, Node.js and RaptorJS
JavaScript
1
star
22

dynamically-generated-static-site

Sample dynamically generated static site
CSS
1
star
23

marko-async-fragment-wrapper

JavaScript
1
star
24

nodejs-training

JavaScript
1
star
25

ghcrawler-in-a-box

Easily start ghcrawler
JavaScript
1
star
26

property-handlers

Utility for mapping object properties to handler functions
JavaScript
1
star
27

deresolve

The inverse of require.resolve()
JavaScript
1
star
28

raptorjs3-kraken-sample-app

JavaScript
1
star