ack-reload

4.0.4 • Public • Published

ack-reload

build status NPM version

Automatically refresh and reload your code in your browser when your code changes. No browser plugins required.

Why?

Restarting your HTTP server and refreshing your browser is annoying.

Table of Contents

How does it work?

ack-reload works in three different ways depending on if you're using it:

  1. Run ack-reload in NodeJs process with full API control using config options
  2. Use ack-reload middleware to "attach" ack-reload to a existing server route
  3. As a command line tool which starts its own Server to monitor the file(s) you're editing for changes and to serve reload-client.js to the browser.

Once reload-server and reload-client are connected, the client side code opens a WebSocket to the server and waits for the WebSocket to close, once it closes, ack-reload waits for the server to come back up (waiting for a socket on open event), once the socket opens we reload the page.

Benefits of ack-reload over original reload package

ack-reload is a fork of the npm package reload

  • Html5Mode
    • ack-reload has the option to make all requests root bound
    • Original reload package does not play well with html5 routing apps
  • onReload option
    • Everytime a websocket reload is issued a callback function can be called
  • Port already in use prompt aka EADDRINUSE prompt
    • Added EADDRINUSE catcher that starts a cli-prompt when desired port is in use. Another port can be supplied to start server on another open port.
  • Native Promises
    • When starting an ack-reload server via the API, a native promise is returned AFTER all services have been started
  • Watching Files
    • Watching files is more intuitive and actually available outside of just the CLI
    • The original reload package does not auto watch files
  • ack-reload does NOT have a name conflict on Ubuntu like reload does
  • Better Logging
    • Better verbose logging where an outside library can mandate how logging occurs
  • Better Client Script Inclusion
    • ack-reload package auto appends client script to all html requests

Express app for ack-reload

var reload = require('ack-reload')
var app = express()
var publicDir = path.join(__dirname, 'public')

//Only host reload software. Create websocket to http attachment. File watching
app.use( reload.middleware(publicDir, server) )

http.createServer(app).listen(3000)

Express app for OLD reload

The following code is how the OLD reload app worked

var reload = require('reload')
var app = express()
var publicDir = path.join(__dirname, 'public')

app.get('/', function (req, res) {
  res.sendFile(path.join(publicDir, 'index.html'))
})

var server = http.createServer(app)

reload(server, app)

server.listen(3000)

Installation

npm install [-g] [--save-dev] ack-reload

Typical Package Installation

npm install --save-dev ack-reload

Typical Global Installation

npm install -g ack-reload

Examples

Three ways to use ack-reload

There are three different ways to use ack-reload.

  1. As a server, allowing ack-reload to host your whole project
  2. As middleware, allowing your exsting server project to utilize ack-reload
  3. As a command line application to serve up static HTML files and be able to reload when the code is altered

Using ack-reload in Express

When used with Express ack-reload creates a new Express route for reload. When you restart the server, the client will detect the server being restarted and automatically refresh the page.

ack-reload can be used in conjunction with tools that allow for automatically restarting the server such as supervisor (recommended), nodemon, forever, etc.

Stand-Alone Example

Serve and watch a folder all in one

server.js:

var reload = require('ack-reload')
var publicDir = path.join(__dirname, 'public')

reload(publicDir,{port:3000})

Express Example

Serve and watch a folder on an existing server

server.js:

var express = require('express')
var http = require('http')
var path = require('path')
var reload = require('ack-reload')
var bodyParser = require('body-parser')
var logger = require('morgan')

var app = express()

var publicDir = path.join(__dirname, 'public')

app.set('port', process.env.PORT || 3000)
app.use(logger('dev'))
app.use(bodyParser.json()) //parses json, multi-part (file), url-encoded

var server = http.createServer(app)

// Reload code only on www url-path from public folder path
app.use("/www" reload.middleware(publicDir, server) )

// Another Reload code here only on admin url-path to admin folder path
var adminPath = path.join(__dirname,'admin')
app.use("/admin", reload.middleware(adminPath, server))

server.listen(app.get('port'), function(){
  console.log("Web server listening on port " + app.get('port'));
});

A demo template that has a change with every reload public/index.html:

<!doctype html>
<html>
  <head>
    <title>Reload Express Sample App</title>
  </head>
  <body>
    <h1>Reload Express Sample App</h1>
    <br />
    <div>Current Time: <script>document.write(Date.now())</script></div>
    <br />
    <div>Script Time: <script src="www/outputTime.js"></script></div>
  </body>
</html>

Manually Reloading

Two ways to approach:

  • Manually call returned reload function after starting a ack-reload server
  • Integrate the reload function into running middleware

Manually Reloading Application

var publicDir = path.join(__dirname, 'public')
var reload = require('ack-reload')

var options = {
  onReload:function(){
    console.log('reload occurred at '+new Date().toString())
  }
}

reload(publicDir, options)
.then(config=>{
  //force reload every 10 seconds of all browser websocket connections
  setInterval(config.reload, 10000);

  //stop reload services after 30 seconds
  setTimeout(function(){
    config.httpServer.close()
  }, 30000)
})
.catch(function(e){
  console.error(e)
})

Manually Reloading With MiddleWare

var publicDir = path.join(__dirname, 'public')
var reload = require('ack-reload')

var server = http.createServer(function(){
  midware(req,res)
})

var midware = reload.middleware(publicDir,server)

//force reload every 10 seconds of all browser websocket connections
setInterval(midware.reload, 10000);

//stop reload services after 30 seconds
setTimeout(function(){
  server.close()
}, 30000)

Advanced Full Featured Example

require('ack-reload')(__dirname,{
  port:8080,
  log:console.log.bind(console),
  open:true,
  message:'reload',
  hostname:'127.0.0.1',
  filter:function(pathTo, stat){
    return stat.isDirectory() || pathTo.search(/\.(js|css|html)$/)>=0
  },
  startPage:'index2.html'
})
.then(function(config){
  //force reload every 10 seconds of all browser websocket connections
  setInterval(config.reload, 10000);

  //stop reload services after 30 seconds
  setTimeout(function(){
    config.httpServer.close()
  }, 30000)  
})
.catch(function(e){
  console.error(e)
})

Integrate with Existing App

The following example takes and existing app, builds a new app, and server both together with ack-reload

Preexisting app.js

const express = require('express');

const app = express();
// LOTS AND LOTS OF MIDDLEWARE HERE...
// server is not created since in this module.
app.use((err, req, res, next) => {
  // final error handler
});

module.exports = app;

serve.js

const app = require('./app');
const http = require('http');
const reload = require('ack-reload');

//tell ack-reload folder to put watch on
const pathToWwwFiles = require('path').join(__dirname,'www');

//Our server that hosts app and reload code
const server = http.createServer(function(req,res){
  if( reload.isRequestForReload(req) ){
    midware(req, res)//html or reload.js request
  }else{
    app(req,res)
  }
});

//watch files, create websocket. Return function to process requests
const midware = reload.middleware(pathToWwwFiles, server)

// at this point we have server and app and reload code
server.listen(8888, () => { console.log('started!') });

API

Middlware

var reload = require('ack-reload')
var midware = reload.middleware(pathTo)

require('http').createServer(function(req,res){
  midware(req,res)
})
.listen(8080,function(){
  if(err){
    console.log(err)
  }else{
    console.log('server started')
  }
})

Arguments

  • pathTo: Folder to watch and serve. Defaults to current dir
  • options:
    • port Number = 8080 - The port to bind to. Can be set with PORT env variable as well.
    • log Function = console.log
    • open Boolean = true - open a browser window
    • message String - when port is in use, tailor prompt messages label
    • hostname String = localhost - This allows for custom hostnames. Defaults to localhost.
    • filter Function - function(pathTo,stat) when function returns true, file will be watched.
    • startPage String - Specify a start page. Defaults to index.html.
    • log Function = console.log - Method to process logging info.
    • watch Boolean = true - Enable/disable watching files. Manual reload will be required
    • html5Mode Boolean = false - Enable/disable always returning root index.html for all html 404 requests
    • onReload Function - Everytime a websocket reload is issued, have a function called

Commands

Using ack-reload as a command line application

There are two ways to use the command line application.

  1. In a directory serving blank static HTML files or
  2. In a project with a package.json file

Each will require different modes of installing.

In case one you should install ack-reload globally with npm install ack-reload -g. Also with ack-reload installed globally you can go to any directory with an HTML file and use the command reload to constantly watch it and reload it while you make changes.

In case two you should install locally with npm install --save-dev, since this tool is to aid in development you should install it as a dev dependency.

Navigate to your html directory:

ack-reload -b

This will open your index.html file in the browser. Any changes that you make will now reload in the browser. You don't need to modify your HTML at all.

Usage for Command Line Application

Example

"scripts": {
  "watch:js": "ack-reload --dir ./dist --html5Mode",
}
Usage: ack-reload [options]

Options:

  -h, --help                      Output usage information
  -V, --version                   Output the version number
  -b, --browser                   Open in the browser automatically.
  -n, --hostname                  If -b flag is being used, this allows for custom hostnames. Defaults to localhost.
  -d, --dir [dir]                 The directory to serve up. Defaults to current dir.
  -e, --exts [extensions]         Extensions separated by commas or pipes. Defaults to html,js,css.
  -p, --port [port]               The port to bind to. Can be set with PORT env variable as well. Defaults to 8080
  -s, --start-page [start-page]		Specify a start page. Defaults to index.html.
  -v, --verbose						        Turns on logging on the server and client side. Defaults to true.
  --html5Mode                     Boolean = false - Enable/disable always returning root index.html for all html 404 requests

Credits

This package was originally a fork and pull-request of reload. My pull request turned out to be too large for the reload team to adopt. My pull request is now it's own package published on NPM.

License

(MIT License)

Copyright 2016, JP Richardson jprichardson@gmail.com

Package Sidebar

Install

npm i ack-reload

Weekly Downloads

3

Version

4.0.4

License

MIT

Unpacked Size

94.5 kB

Total Files

32

Last publish

Collaborators

  • ackerapple