Browse Source

added --verbose option to aid debugging

master
Lloyd Brookes 9 years ago
parent
commit
e6351e9651
  1. 7
      README.md
  2. 14
      bin/cli.js
  3. 7
      jsdoc2md/README.hbs
  4. 4
      lib/cli-options.js
  5. 29
      lib/local-web-server.js
  6. 3
      package.json

7
README.md

@ -128,6 +128,13 @@ The format value supplied is passed directly to [morgan](https://github.com/expr
### Other usage ### Other usage
#### Debugging
Prints information about loaded middleware, arguments, remote proxy fetches etc.
```sh
$ ws --verbose
```
#### Compression #### Compression
Serve gzip-compressed resources, where applicable Serve gzip-compressed resources, where applicable

14
bin/cli.js

@ -6,6 +6,7 @@ const commandLineArgs = require('command-line-args')
const ansi = require('ansi-escape-sequences') const ansi = require('ansi-escape-sequences')
const loadConfig = require('config-master') const loadConfig = require('config-master')
const path = require('path') const path = require('path')
const s = require('string-tools')
const cli = commandLineArgs(cliOptions.definitions) const cli = commandLineArgs(cliOptions.definitions)
const usage = cli.getUsage(cliOptions.usageData) const usage = cli.getUsage(cliOptions.usageData)
@ -23,7 +24,7 @@ if (options.misc.config) {
process.exit(0) process.exit(0)
} }
localWebServer({
const app = localWebServer({
static: { static: {
root: options.server.directory, root: options.server.directory,
options: { options: {
@ -45,8 +46,15 @@ localWebServer({
forbid: options.server.forbid, forbid: options.server.forbid,
spa: options.server.spa, spa: options.server.spa,
'no-cache': options.server['no-cache'], 'no-cache': options.server['no-cache'],
rewrite: options.server.rewrite
}).listen(options.server.port, onServerUp)
rewrite: options.server.rewrite,
verbose: options.server.verbose
})
app
.on('verbose', (category, message) => {
console.error(ansi.format(s.padRight(category, 14), 'bold'), message)
})
.listen(options.server.port, onServerUp)
function halt (err) { function halt (err) {
console.log(ansi.format(`Error: ${err.message}`, 'red')) console.log(ansi.format(`Error: ${err.message}`, 'red'))

7
jsdoc2md/README.hbs

@ -128,6 +128,13 @@ The format value supplied is passed directly to [morgan](https://github.com/expr
### Other usage ### Other usage
#### Debugging
Prints information about loaded middleware, arguments, remote proxy fetches etc.
```sh
$ ws --verbose
```
#### Compression #### Compression
Serve gzip-compressed resources, where applicable Serve gzip-compressed resources, where applicable

4
lib/cli-options.js

@ -33,6 +33,10 @@ module.exports = {
description: 'Path to a Single Page App, e.g. app.html', group: 'server' description: 'Path to a Single Page App, e.g. app.html', group: 'server'
}, },
{ {
name: 'verbose', type: Boolean,
description: 'Verbose output, useful for debugging.', group: 'server'
},
{
name: 'help', alias: 'h', type: Boolean, name: 'help', alias: 'h', type: Boolean,
description: 'Print these usage instructions', group: 'misc' description: 'Print these usage instructions', group: 'misc'
}, },

29
lib/local-web-server.js

@ -39,7 +39,8 @@ function localWebServer (options) {
compress: false, compress: false,
mime: {}, mime: {},
forbid: [], forbid: [],
rewrite: []
rewrite: [],
verbose: false
}, options) }, options)
const log = options.log const log = options.log
@ -48,6 +49,16 @@ function localWebServer (options) {
const app = new Koa() const app = new Koa()
const _use = app.use const _use = app.use
app.use = x => _use.call(app, convert(x)) app.use = x => _use.call(app, convert(x))
function verbose (category, message) {
if (options.verbose) {
process.nextTick(() => app.emit('verbose', category, message))
}
}
app._verbose = verbose
if (options.verbose && !log.format) {
log.format = 'none'
}
/* CORS: allow from any origin */ /* CORS: allow from any origin */
app.use(cors()) app.use(cors())
@ -57,9 +68,11 @@ function localWebServer (options) {
options.rewrite.forEach(route => { options.rewrite.forEach(route => {
if (route.to) { if (route.to) {
if (url.parse(route.to).host) { if (url.parse(route.to).host) {
app.use(_.all(route.from, proxyRequest(route)))
verbose('proxy rewrite', `${route.from} -> ${route.to}`)
app.use(_.all(route.from, proxyRequest(route, app)))
} else { } else {
const rewrite = require('koa-rewrite') const rewrite = require('koa-rewrite')
verbose('local rewrite', `${route.from} -> ${route.to}`)
app.use(rewrite(route.from, route.to)) app.use(rewrite(route.from, route.to))
} }
} }
@ -68,6 +81,7 @@ function localWebServer (options) {
/* path blacklist */ /* path blacklist */
if (options.forbid.length) { if (options.forbid.length) {
verbose('forbid', options.forbid.join(', '))
app.use(blacklist(options.forbid)) app.use(blacklist(options.forbid))
} }
@ -75,12 +89,14 @@ function localWebServer (options) {
if (!options['no-cache']) { if (!options['no-cache']) {
const conditional = require('koa-conditional-get') const conditional = require('koa-conditional-get')
const etag = require('koa-etag') const etag = require('koa-etag')
verbose('etag caching', 'enabled')
app.use(conditional()) app.use(conditional())
app.use(etag()) app.use(etag())
} }
/* mime-type overrides */ /* mime-type overrides */
if (options.mime) { if (options.mime) {
verbose('mime override', JSON.stringify(options.mime))
app.use((ctx, next) => { app.use((ctx, next) => {
return next().then(() => { return next().then(() => {
const reqPathExtension = path.extname(ctx.path).slice(1) const reqPathExtension = path.extname(ctx.path).slice(1)
@ -95,6 +111,7 @@ function localWebServer (options) {
/* compress response */ /* compress response */
if (options.compress) { if (options.compress) {
const compress = require('koa-compress') const compress = require('koa-compress')
verbose('compression', 'enabled')
app.use(compress()) app.use(compress())
} }
@ -117,18 +134,21 @@ function localWebServer (options) {
/* serve static files */ /* serve static files */
if (options.static.root) { if (options.static.root) {
const serve = require('koa-static') const serve = require('koa-static')
verbose('static', `root: ${options.static.root} options: ${JSON.stringify(options.static.options)}` )
app.use(serve(options.static.root, options.static.options)) app.use(serve(options.static.root, options.static.options))
} }
/* serve directory index */ /* serve directory index */
if (options.serveIndex.path) { if (options.serveIndex.path) {
const serveIndex = require('koa-serve-index') const serveIndex = require('koa-serve-index')
verbose('serve-index', `root: ${options.serveIndex.path} options: ${JSON.stringify(options.serveIndex.options)}` )
app.use(serveIndex(options.serveIndex.path, options.serveIndex.options)) app.use(serveIndex(options.serveIndex.path, options.serveIndex.options))
} }
/* for any URL not matched by static (e.g. `/search`), serve the SPA */ /* for any URL not matched by static (e.g. `/search`), serve the SPA */
if (options.spa) { if (options.spa) {
const send = require('koa-send') const send = require('koa-send')
verbose('SPA', options.spa)
app.use(_.all('*', function * () { app.use(_.all('*', function * () {
yield send(this, options.spa, { root: path.resolve(options.static.root) || process.cwd() }) yield send(this, options.spa, { root: path.resolve(options.static.root) || process.cwd() })
})) }))
@ -141,7 +161,7 @@ function logstalgiaDate () {
return (`${d.getDate()}/${d.getUTCMonth()}/${d.getFullYear()}:${d.toTimeString()}`).replace('GMT', '').replace(' (BST)', '') return (`${d.getDate()}/${d.getUTCMonth()}/${d.getFullYear()}:${d.toTimeString()}`).replace('GMT', '').replace(' (BST)', '')
} }
function proxyRequest (route) {
function proxyRequest (route, app) {
const httpProxy = require('http-proxy') const httpProxy = require('http-proxy')
const proxy = httpProxy.createProxyServer({ const proxy = httpProxy.createProxyServer({
changeOrigin: true changeOrigin: true
@ -168,12 +188,13 @@ function proxyRequest (route) {
} }
this.response = false this.response = false
app._verbose('proxy request', `from: ${this.path}, to: ${url.parse(route.new).href}`)
proxy.once('error', err => { proxy.once('error', err => {
this.throw(500, `[PROXY] ${err.message}: ${route.new}`) this.throw(500, `[PROXY] ${err.message}: ${route.new}`)
}) })
proxy.once('proxyReq', function (proxyReq) { proxy.once('proxyReq', function (proxyReq) {
proxyReq.path = url.parse(route.new).path;
proxyReq.path = url.parse(route.new).path
}) })
proxy.web(this.req, this.res, { target: route.new }) proxy.web(this.req, this.res, { target: route.new })
} }

3
package.json

@ -45,7 +45,8 @@
"koa-serve-index": "^1.1.0", "koa-serve-index": "^1.1.0",
"koa-static": "^1.5.2", "koa-static": "^1.5.2",
"path-to-regexp": "^1.2.1", "path-to-regexp": "^1.2.1",
"stream-log-stats": "^v1.1.0-0"
"stream-log-stats": "^v1.1.0-0",
"string-tools": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"req-then": "^0.2.2", "req-then": "^0.2.2",

Loading…
Cancel
Save