From f11956acd6ef25ec1c12451386a73b6b2f109c73 Mon Sep 17 00:00:00 2001 From: Shannon Moeller Date: Sun, 11 Oct 2020 16:26:39 -0400 Subject: [PATCH] tweaks and rework --- README.md | 31 +++++++++------- cli.js | 23 ++++++------ example/app.html | 3 ++ {test => example}/index.html | 2 +- index.js | 70 ++++++++++++++++++++++-------------- package-lock.json | 5 --- package.json | 3 +- 7 files changed, 79 insertions(+), 58 deletions(-) create mode 100644 example/app.html rename {test => example}/index.html (67%) diff --git a/README.md b/README.md index ad51394..df5de48 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![NPM version][npm-img]][npm-url] [![Downloads][downloads-img]][npm-url] -A simple static-file server with live reload support for development. The word itself derives from the French _livrée_, meaning _dispensed_ or _handed over_. +Minimal development server to watch and dispense static files. ## Install @@ -15,42 +15,47 @@ $ npm install --global livery ## Usage ```man -Usage: livery [options] [path] - lr [options] [path] +Usage: livery [] [--] [] + lr [] [--] [] Options: -d, --delay Debounce delay for reloads. (default: 250) - -g, --glob Glob of files to watch. (default: '**/*.*') -h, --help Output usage information. + -l, --live LiveReload server port. (default: 35729) -p, --port HTTP server port. (default: 3000) -s, --spa Single-page app. If string, path to html. (default: false) + -w, --watch Glob or globs of files to watch. (default: '**/*.*') Examples: $ lr - $ lr src - $ livery --glob 'src/**/*.*' --glob 'test/**/*.js' --spa -- dist - $ livery --delay 1000 --spa /spa.html + $ lr -p 8080 public + $ livery --watch 'src/**/*.*' --watch 'test/**/*.js' dist + $ livery --spa -- static + $ livery --spa app.html ``` ## API -### `livery([options]): Object` +### `livery([dir, [options]]): Object` +- `dir` `{String}` Directory of static files. (default: `.`) - `options` `{Object}` - `delay` `{Number}` Debounce delay for reloads. (default: `250`) - - `glob` `{String|Array}` Glob or globs of files to watch. (default: `**/*.*`) - - `port` `{Number}` HTTP server port. (default: `3000`) + - `httpPort` `{Number}` HTTP server port. (default: `3000`) + - `livePort` `{Number}` LiveReload server port. (default: `35729`) - `spa` `{Boolean|String}` Single-page app. If string, path to html. (default: `false`). + - `watch` `{String|Array}` Glob or globs of files to watch. (default: `**/*.*`) Starts an HTTP server, LiveReload server, and file watcher. ```js const livery = require('livery'); -const { httpServer, liveServer, watcher } = livery({ +const { httpServer, liveServer, fileWatcher } = livery({ delay: 250, - glob: '**/*.*', - port: 3000, + httpPort: 3000, + livePort: 35729, spa: false, + watch: '**/*.*', }); ``` diff --git a/cli.js b/cli.js index acbb6a5..b4dce36 100755 --- a/cli.js +++ b/cli.js @@ -4,38 +4,39 @@ import minimist from 'minimist'; import livery from './index.js'; const usage = ` -Usage: livery [options] [path] - lr [options] [path] +Usage: livery [] [--] [] + lr [] [--] [] Options: -d, --delay Debounce delay for reloads. (default: 250) - -g, --glob Glob of files to watch. (default: '**/*.*') -h, --help Output usage information. + -l, --live LiveReload server port. (default: 35729) -p, --port HTTP server port. (default: 3000) -s, --spa Single-page app. If string, path to html. (default: false) + -w, --watch Glob or globs of files to watch. (default: '**/*.*') Examples: $ lr - $ lr src - $ livery --glob 'src/**/*.*' --glob 'test/**/*.js' --spa -- dist - $ livery --delay 1000 --spa /spa.html + $ lr -p 8080 public + $ livery --watch 'src/**/*.*' --watch 'test/**/*.js' dist + $ livery --spa -- static + $ livery --spa app.html `; const args = minimist(process.argv.slice(2), { alias: { d: 'delay', - g: 'glob', h: 'help', - p: 'port', + l: ['live', 'livePort'], + p: ['port', 'httpPort'], s: 'spa', + w: 'watch', }, - boolean: ['help'], - string: ['glob'], }); if (args.help) { console.log(usage.trim()); } else { - livery(args); + livery(args._[0], args); process.stdin.pipe(process.stdout); } diff --git a/example/app.html b/example/app.html new file mode 100644 index 0000000..ba2b428 --- /dev/null +++ b/example/app.html @@ -0,0 +1,3 @@ + +App +

Spa day!

diff --git a/test/index.html b/example/index.html similarity index 67% rename from test/index.html rename to example/index.html index 924877b..d896327 100644 --- a/test/index.html +++ b/example/index.html @@ -1,3 +1,3 @@ -Hello +Index

You look nice today.

diff --git a/index.js b/index.js index e689f4b..0fe650c 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,13 @@ import http from 'http'; +import os from 'os'; import path from 'path'; import chokidar from 'chokidar'; -import ip from 'ip'; import send from 'send'; import tiny from 'tiny-lr'; +const cwd = process.cwd(); +const interfaces = os.networkInterfaces(); + function debounce(fn, ms) { let timer; @@ -14,10 +17,28 @@ function debounce(fn, ms) { }; } -export default function livery(options) { - const { delay = 250, glob = '**/*.*', port = 3000, spa } = options || {}; - const address = ip.address(); - const root = path.join(process.cwd(), options._[0] || '.'); +function getIpAddress() { + const values = Object.values(interfaces).flat(); + + for (const { address, family, internal } of values) { + if (family === 'IPv4' && !internal) { + return address; + } + } +} + +export default function livery(dir = '.', options = {}) { + const { + delay = 250, + httpPort = 3000, + livePort = 35729, + spa = false, + watch = '**/*.*', + } = options; + + const rootPath = path.join(cwd, dir); + const spaPath = spa === true ? 'index.html' : spa; + const address = getIpAddress(); // HTTP Server @@ -26,25 +47,23 @@ export default function livery(options) { function serveSpa(error) { const isSpa = - spa && + spaPath && error.statusCode === 404 && req.headers.accept.includes('html'); if (isSpa) { - const url = spa === true ? '/index.html' : spa; - - send(req, url, { root }).pipe(res); + send(req, spaPath, { root: rootPath }).pipe(res); } else { res.statusCode = error.statusCode || 500; res.end(); } } - send(req, req.url, { root }).on('error', serveSpa).pipe(res); + send(req, req.url, { root: rootPath }).on('error', serveSpa).pipe(res); }); httpServer.on('error', console.error); - httpServer.listen(port); + httpServer.listen(httpPort); // LiveReload Server @@ -54,37 +73,36 @@ export default function livery(options) { }); liveServer.on('error', console.error); - liveServer.listen(35729); + liveServer.listen(livePort); - const reload = debounce(() => { + function reload() { console.log('RELOAD'); - Object.keys(liveServer.clients).forEach((id) => { - liveServer.clients[id].reload(['*']); - }); - }, delay); + + for (const client of Object.values(liveServer.clients)) { + client.reload(['*']); + } + } // File Watcher - const watcher = chokidar.watch(glob, { + const fileWatcher = chokidar.watch(watch, { ignored: '**/node_modules/**', ignoreInitial: true, persistent: true, }); - watcher.on('error', console.error); - watcher.on('add', reload); - watcher.on('change', reload); - watcher.on('unlink', reload); + fileWatcher.on('error', console.error); + fileWatcher.on('all', debounce(reload, delay)); // Report - console.log(`HTTP: http://${address}:${port}`); - console.log(`Live: http://${address}:35729`); - console.log(`Watch: ${glob}`); + console.log(`HTTP Server: http://${address}:${httpPort}`); + console.log(`Live Server: http://${address}:${livePort}`); + console.log(`File Watcher: ${watch}`); return { httpServer, liveServer, - watcher, + fileWatcher, }; } diff --git a/package-lock.json b/package-lock.json index 2a36f32..1e7ef4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -172,11 +172,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", diff --git a/package.json b/package.json index 983050e..382d9ec 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "livery", "version": "3.3.0", - "description": "Minimal dev server to dispense static files.", + "description": "Minimal development server to watch and dispense static files.", "author": "Shannon Moeller (http://shannonmoeller.com)", "repository": "shannonmoeller/livery", "license": "MIT", @@ -22,7 +22,6 @@ }, "dependencies": { "chokidar": "^3.4.2", - "ip": "^1.1.5", "minimist": "^1.2.5", "send": "^0.17.1", "tiny-lr": "^2.0.0"