You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

647 lines
22 KiB

9 years ago
11 years ago
9 years ago
11 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
12 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
11 years ago
12 years ago
9 years ago
9 years ago
9 years ago
9 years ago
11 years ago
9 years ago
9 years ago
11 years ago
11 years ago
9 years ago
11 years ago
9 years ago
9 years ago
9 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
9 years ago
11 years ago
12 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
11 years ago
9 years ago
11 years ago
9 years ago
10 years ago
9 years ago
  1. [![view on npm](http://img.shields.io/npm/v/local-web-server.svg)](https://www.npmjs.org/package/local-web-server)
  2. [![npm module downloads](http://img.shields.io/npm/dt/local-web-server.svg)](https://www.npmjs.org/package/local-web-server)
  3. [![Build Status](https://travis-ci.org/75lb/local-web-server.svg?branch=master)](https://travis-ci.org/75lb/local-web-server)
  4. [![Dependency Status](https://david-dm.org/75lb/local-web-server.svg)](https://david-dm.org/75lb/local-web-server)
  5. [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/feross/standard)
  6. [![Join the chat at https://gitter.im/75lb/local-web-server](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/75lb/local-web-server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
  7. ***This project does not yet use the latest Koa modules (some dependencies are out of date) because the recent Koa upgrade made node v7.6 the minimum supported version. This tool works with node v4.0.0 or higher. However, local-web-server v2 will likely require node v7.6 and above.***
  8. # local-web-server
  9. A simple web-server for productive front-end development. Typical use cases:
  10. * Front-end Development
  11. * Static or Single Page App development
  12. * Re-route paths to local or remote resources
  13. * Efficient, predictable, entity-tag-powered conditional request handling (no need to 'Disable Cache' in DevTools, slowing page-load down)
  14. * Bundle with your front-end project
  15. * Very little configuration, just a few options
  16. * Outputs a dynamic statistics view to the terminal
  17. * Configurable log output, compatible with [Goaccess, Logstalgia and glTail](https://github.com/75lb/local-web-server/blob/master/doc/visualisation.md)
  18. * Back-end service mocking
  19. * Prototype a web service, microservice, REST API etc.
  20. * Mocks are defined with config (static), or code (dynamic).
  21. * CORS-friendly, all origins allowed by default.
  22. * Proxy server
  23. * Map local routes to remote servers. Removes CORS pain when consuming remote services.
  24. * HTTPS server
  25. * HTTPS is strictly required by some modern techs (ServiceWorker, Media Capture and Streams etc.)
  26. * File sharing
  27. ## Synopsis
  28. local-web-server is a simple command-line tool. To use it, from your project directory run `ws`.
  29. <pre><code>$ ws --help
  30. <strong>local-web-server</strong>
  31. A simple web-server for productive front-end development.
  32. <strong>Synopsis</strong>
  33. $ ws [&lt;server options&gt;]
  34. $ ws --config
  35. $ ws --help
  36. <strong>Server</strong>
  37. -p, --port number Web server port.
  38. -d, --directory path Root directory, defaults to the current directory.
  39. -f, --log-format string If a format is supplied an access log is written to stdout. If
  40. not, a dynamic statistics view is displayed. Use a preset ('none',
  41. 'dev','combined', 'short', 'tiny' or 'logstalgia') or supply a
  42. custom format (e.g. ':method -> :url').
  43. -r, --rewrite expression ... A list of URL rewrite rules. For each rule, separate the 'from'
  44. and 'to' routes with '->'. Whitespace surrounded the routes is
  45. ignored. E.g. '/from -> /to'.
  46. -s, --spa file Path to a Single Page App, e.g. app.html.
  47. -c, --compress Serve gzip-compressed resources, where applicable.
  48. -b, --forbid path ... A list of forbidden routes.
  49. -n, --no-cache Disable etag-based caching -forces loading from disk each request.
  50. --key file SSL key. Supply along with --cert to launch a https server.
  51. --cert file SSL cert. Supply along with --key to launch a https server.
  52. --https Enable HTTPS using a built-in key and cert, registered to the
  53. domain 127.0.0.1.
  54. --verbose Verbose output, useful for debugging.
  55. <strong>Misc</strong>
  56. -h, --help Print these usage instructions.
  57. --config Print the stored config.
  58. Project home: https://github.com/75lb/local-web-server
  59. </code></pre>
  60. ## Examples
  61. For the examples below, we assume we're in a project directory looking like this:
  62. ```sh
  63. .
  64. ├── css
  65. │   └── style.css
  66. ├── index.html
  67. └── package.json
  68. ```
  69. **All paths/routes are specified using [express syntax](http://expressjs.com/guide/routing.html#route-paths)**. To run the example projects linked below, clone the project, move into the example directory specified, run `ws`.
  70. ### Static site
  71. Fire up your static site on the default port:
  72. ```sh
  73. $ ws
  74. serving at http://localhost:8000
  75. ```
  76. [Example](https://github.com/75lb/local-web-server/tree/master/example/simple).
  77. ### Single Page Application
  78. You're building a web app with client-side routing, so mark `index.html` as the SPA.
  79. ```sh
  80. $ ws --spa index.html
  81. ```
  82. By default, typical SPA paths (e.g. `/user/1`, `/login`) would return `404 Not Found` as a file does not exist with that path. By marking `index.html` as the SPA you create this rule:
  83. *If a static file at the requested path exists (e.g. `/css/style.css`) then serve it, if it does not (e.g. `/login`) then serve the specified SPA and handle the route client-side.*
  84. [Example](https://github.com/75lb/local-web-server/tree/master/example/spa).
  85. ### URL rewriting
  86. Your application requested `/css/style.css` but it's stored at `/build/css/style.css`. To avoid a 404 you need a rewrite rule:
  87. ```sh
  88. $ ws --rewrite '/css/style.css -> /build/css/style.css'
  89. ```
  90. Or, more generally (matching any stylesheet under `/css`):
  91. ```sh
  92. $ ws --rewrite '/css/:stylesheet -> /build/css/:stylesheet'
  93. ```
  94. With a deep CSS directory structure it may be easier to mount the entire contents of `/build/css` to the `/css` path:
  95. ```sh
  96. $ ws --rewrite '/css/* -> /build/css/$1'
  97. ```
  98. this rewrites `/css/a` as `/build/css/a`, `/css/a/b/c` as `/build/css/a/b/c` etc.
  99. #### Proxied requests
  100. If the `to` URL contains a remote host, local-web-server will act as a proxy - fetching and responding with the remote resource.
  101. Mount the npm registry locally:
  102. ```sh
  103. $ ws --rewrite '/npm/* -> http://registry.npmjs.org/$1'
  104. ```
  105. Map local requests for repo data to the Github API:
  106. ```sh
  107. $ ws --rewrite '/:user/repos/:name -> https://api.github.com/repos/:user/:name'
  108. ```
  109. [Example](https://github.com/75lb/local-web-server/tree/master/example/rewrite).
  110. ### Mock Responses
  111. Mocks give you full control over the response headers and body returned to the client. They can be used to return anything from a simple html string to a resourceful REST API. Typically, they're used to mock services but can be used for anything.
  112. In the config, define an array called `mocks`. Each mock definition maps a <code>[route](http://expressjs.com/guide/routing.html#route-paths)</code> to a `response`. A simple home page:
  113. ```json
  114. {
  115. "mocks": [
  116. {
  117. "route": "/",
  118. "response": {
  119. "body": "<h1>Welcome to the Mock Responses example</h1>"
  120. }
  121. }
  122. ]
  123. }
  124. ```
  125. Under the hood, the property values from the `response` object are written onto the underlying [koa response object](https://github.com/koajs/koa/blob/master/docs/api/response.md). You can set any valid koa response properies, for example [type](https://github.com/koajs/koa/blob/master/docs/api/response.md#responsetype-1):
  126. ```json
  127. {
  128. "mocks": [
  129. {
  130. "route": "/",
  131. "response": {
  132. "type": "text/plain",
  133. "body": "<h1>Welcome to the Mock Responses example</h1>"
  134. }
  135. }
  136. ]
  137. }
  138. ```
  139. #### Conditional Response
  140. To define a conditional response, set a `request` object on the mock definition. The `request` value acts as a query - the response defined will only be returned if each property of the `request` query matches. For example, return an XML response *only* if the request headers include `accept: application/xml`, else return 404 Not Found.
  141. ```json
  142. {
  143. "mocks": [
  144. {
  145. "route": "/two",
  146. "request": { "accepts": "xml" },
  147. "response": {
  148. "body": "<result id='2' name='whatever' />"
  149. }
  150. }
  151. ]
  152. }
  153. ```
  154. #### Multiple Potential Responses
  155. To specify multiple potential responses, set an array of mock definitions to the `responses` property. The first response with a matching request query will be sent. In this example, the client will get one of two responses depending on the request method:
  156. ```json
  157. {
  158. "mocks": [
  159. {
  160. "route": "/three",
  161. "responses": [
  162. {
  163. "request": { "method": "GET" },
  164. "response": {
  165. "body": "<h1>Mock response for 'GET' request on /three</h1>"
  166. }
  167. },
  168. {
  169. "request": { "method": "POST" },
  170. "response": {
  171. "status": 400,
  172. "body": { "message": "That method is not allowed." }
  173. }
  174. }
  175. ]
  176. }
  177. ]
  178. }
  179. ```
  180. #### Dynamic Response
  181. The examples above all returned static data. To define a dynamic response, create a mock module. Specify its path in the `module` property:
  182. ```json
  183. {
  184. "mocks": [
  185. {
  186. "route": "/four",
  187. "module": "/mocks/stream-self.js"
  188. }
  189. ]
  190. }
  191. ```
  192. Here's what the `stream-self` module looks like. The module should export a mock definition (an object, or array of objects, each with a `response` and optional `request`). In this example, the module simply streams itself to the response but you could set `body` to *any* [valid value](https://github.com/koajs/koa/blob/master/docs/api/response.md#responsebody-1).
  193. ```js
  194. const fs = require('fs')
  195. module.exports = {
  196. response: {
  197. body: fs.createReadStream(__filename)
  198. }
  199. }
  200. ```
  201. #### Response function
  202. For more power, define the response as a function. It will receive the [koa context](https://github.com/koajs/koa/blob/master/docs/api/context.md) as its first argument. Now you have full programmatic control over the response returned.
  203. ```js
  204. module.exports = {
  205. response: function (ctx) {
  206. ctx.body = '<h1>I can do anything i want.</h1>'
  207. }
  208. }
  209. ```
  210. If the route contains tokens, their values are passed to the response. For example, with this mock...
  211. ```json
  212. {
  213. "mocks": [
  214. {
  215. "route": "/players/:id",
  216. "module": "/mocks/players.js"
  217. }
  218. ]
  219. }
  220. ```
  221. ...the `id` value is passed to the `response` function. For example, a path of `/players/10?name=Lionel` would pass `10` to the response function. Additional, the value `Lionel` would be available on `ctx.query.name`:
  222. ```js
  223. module.exports = {
  224. response: function (ctx, id) {
  225. ctx.body = `<h1>id: ${id}, name: ${ctx.query.name}</h1>`
  226. }
  227. }
  228. ```
  229. #### RESTful Resource example
  230. Here's an example of a REST collection (users). We'll create two routes, one for actions on the resource collection, one for individual resource actions.
  231. ```json
  232. {
  233. "mocks": [
  234. { "route": "/users", "module": "/mocks/users.js" },
  235. { "route": "/users/:id", "module": "/mocks/user.js" }
  236. ]
  237. }
  238. ```
  239. Define a module (`users.json`) defining seed data:
  240. ```json
  241. [
  242. { "id": 1, "name": "Lloyd", "age": 40, "nationality": "English" },
  243. { "id": 2, "name": "Mona", "age": 34, "nationality": "Palestinian" },
  244. { "id": 3, "name": "Francesco", "age": 24, "nationality": "Italian" }
  245. ]
  246. ```
  247. The collection module:
  248. ```js
  249. const users = require('./users.json')
  250. /* responses for /users */
  251. const mockResponses = [
  252. /* Respond with 400 Bad Request for PUT and DELETE - inappropriate on a collection */
  253. { request: { method: 'PUT' }, response: { status: 400 } },
  254. { request: { method: 'DELETE' }, response: { status: 400 } },
  255. {
  256. /* for GET requests return a subset of data, optionally filtered on 'minAge' and 'nationality' */
  257. request: { method: 'GET' },
  258. response: function (ctx) {
  259. ctx.body = users.filter(user => {
  260. const meetsMinAge = (user.age || 1000) >= (Number(ctx.query.minAge) || 0)
  261. const requiredNationality = user.nationality === (ctx.query.nationality || user.nationality)
  262. return meetsMinAge && requiredNationality
  263. })
  264. }
  265. },
  266. {
  267. /* for POST requests, create a new user and return the path to the new resource */
  268. request: { method: 'POST' },
  269. response: function (ctx) {
  270. const newUser = ctx.request.body
  271. users.push(newUser)
  272. newUser.id = users.length
  273. ctx.status = 201
  274. ctx.response.set('Location', `/users/${newUser.id}`)
  275. }
  276. }
  277. ]
  278. module.exports = mockResponses
  279. ```
  280. The individual resource module:
  281. ```js
  282. const users = require('./users.json')
  283. /* responses for /users/:id */
  284. const mockResponses = [
  285. /* don't support POST here */
  286. { request: { method: 'POST' }, response: { status: 400 } },
  287. /* for GET requests, return a particular user */
  288. {
  289. request: { method: 'GET' },
  290. response: function (ctx, id) {
  291. ctx.body = users.find(user => user.id === Number(id))
  292. }
  293. },
  294. /* for PUT requests, update the record */
  295. {
  296. request: { method: 'PUT' },
  297. response: function (ctx, id) {
  298. const updatedUser = ctx.request.body
  299. const existingUserIndex = users.findIndex(user => user.id === Number(id))
  300. users.splice(existingUserIndex, 1, updatedUser)
  301. ctx.status = 200
  302. }
  303. },
  304. /* DELETE request: remove the record */
  305. {
  306. request: { method: 'DELETE' },
  307. response: function (ctx, id) {
  308. const existingUserIndex = users.findIndex(user => user.id === Number(id))
  309. users.splice(existingUserIndex, 1)
  310. ctx.status = 200
  311. }
  312. }
  313. ]
  314. module.exports = mockResponses
  315. ```
  316. [Example](https://github.com/75lb/local-web-server/tree/master/example/mock).
  317. ### HTTPS Server
  318. Some modern techs (ServiceWorker, any `MediaDevices.getUserMedia()` request etc.) *must* be served from a secure origin (HTTPS). To launch an HTTPS server, supply a `--key` and `--cert` to local-web-server, for example:
  319. ```
  320. $ ws --key localhost.key --cert localhost.crt
  321. ```
  322. If you don't have a key and certificate it's trivial to create them. You do not need third-party verification (Verisign etc.) for development purposes. To get the green padlock in the browser, the certificate..
  323. * must have a `Common Name` value matching the FQDN of the server
  324. * must be verified by a Certificate Authority (but we can overrule this - see below)
  325. First create a certificate:
  326. 1. Install openssl.
  327. `$ brew install openssl`
  328. 2. Generate a RSA private key.
  329. `$ openssl genrsa -des3 -passout pass:x -out ws.pass.key 2048`
  330. 3. Create RSA key.
  331. ```
  332. $ openssl rsa -passin pass:x -in ws.pass.key -out ws.key
  333. ```
  334. 4. Create certificate request. The command below will ask a series of questions about the certificate owner. The most imporant answer to give is for `Common Name`, you can accept the default values for the others. **Important**: you **must** input your server's correct FQDN (`dev-server.local`, `laptop.home` etc.) into the `Common Name` field. The cert is only valid for the domain specified here. You can find out your computers host name by running the command `hostname`. For example, mine is `mba3.home`.
  335. `$ openssl req -new -key ws.key -out ws.csr`
  336. 5. Generate self-signed certificate.
  337. `$ openssl x509 -req -days 365 -in ws.csr -signkey ws.key -out ws.crt`
  338. 6. Clean up files we're finished with
  339. `$ rm ws.pass.key ws.csr`
  340. 7. Launch HTTPS server. In iTerm, control-click the first URL (with the hostname matching `Common Name`) to launch your browser.
  341. ```
  342. $ ws --key ws.key --cert ws.crt
  343. serving at https://mba3.home:8010, https://127.0.0.1:8010, https://192.168.1.203:8010
  344. ```
  345. Chrome and Firefox will still complain your certificate has not been verified by a Certificate Authority. Firefox will offer you an `Add an exception` option, allowing you to ignore the warning and manually mark the certificate as trusted. In Chrome on Mac, you can manually trust the certificate another way:
  346. 1. Open Keychain
  347. 2. Click File -> Import. Select the `.crt` file you created.
  348. 3. In the `Certificates` category, double-click the cert you imported.
  349. 4. In the `trust` section, underneath `when using this certificate`, select `Always Trust`.
  350. Now you have a valid, trusted certificate for development.
  351. #### Built-in certificate
  352. As a quick win, you can run `ws` with the `https` flag. This will launch an HTTPS server using a [built-in certificate](https://github.com/75lb/local-web-server/tree/master/ssl) registered to the domain 127.0.0.1.
  353. ### Stored config
  354. Use the same options every time? Persist then to `package.json`:
  355. ```json
  356. {
  357. "name": "example",
  358. "version": "1.0.0",
  359. "local-web-server": {
  360. "port": 8100,
  361. "forbid": "*.json"
  362. }
  363. }
  364. ```
  365. or `.local-web-server.json`
  366. ```json
  367. {
  368. "port": 8100,
  369. "forbid": "*.json"
  370. }
  371. ```
  372. local-web-server will merge and use all config found, searching from the current directory upward. In the case both `package.json` and `.local-web-server.json` config is found in the same directory, `.local-web-server.json` will take precedence. Options set on the command line take precedence over all.
  373. To inspect stored config, run:
  374. ```sh
  375. $ ws --config
  376. ```
  377. ### Logging
  378. By default, local-web-server outputs a simple, dynamic statistics view. To see traditional web server logs, use `--log-format`:
  379. ```sh
  380. $ ws --log-format combined
  381. serving at http://localhost:8000
  382. ::1 - - [16/Nov/2015:11:16:52 +0000] "GET / HTTP/1.1" 200 12290 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2562.0 Safari/537.36"
  383. ```
  384. The format value supplied is passed directly to [morgan](https://github.com/expressjs/morgan). The exception is `--log-format none` which disables all output.
  385. ### Access Control
  386. By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
  387. ```sh
  388. $ ws --forbid '*.json' '*.yml'
  389. serving at http://localhost:8000
  390. ```
  391. [Example](https://github.com/75lb/local-web-server/tree/master/example/forbid).
  392. ### Other usage
  393. #### Debugging
  394. Prints information about loaded middleware, arguments, remote proxy fetches etc.
  395. ```sh
  396. $ ws --verbose
  397. ```
  398. #### Compression
  399. Serve gzip-compressed resources, where applicable
  400. ```sh
  401. $ ws --compress
  402. ```
  403. #### Disable caching
  404. Disable etag response headers, forcing resources to be served in full every time.
  405. ```sh
  406. $ ws --no-cache
  407. ```
  408. #### mime-types
  409. You can set additional mime-type/extension mappings, or override the defaults by setting a `mime` value in the stored config. This value is passed directly to [mime.define()](https://github.com/broofa/node-mime#mimedefine). Example:
  410. ```json
  411. {
  412. "mime": {
  413. "text/plain": [ "php", "pl" ]
  414. }
  415. }
  416. ```
  417. [Example](https://github.com/75lb/local-web-server/tree/master/example/mime-override).
  418. #### Log Visualisation
  419. Instructions for how to visualise log output using goaccess, logstalgia or gltail [here](https://github.com/75lb/local-web-server/blob/master/doc/visualisation.md).
  420. ## Install
  421. Ensure [node.js](http://nodejs.org) is installed first. Linux/Mac users may need to run the following commands with `sudo`.
  422. ```sh
  423. $ npm install -g local-web-server
  424. ```
  425. This will install the `ws` tool globally. To see the available options, run:
  426. ```sh
  427. $ ws --help
  428. ```
  429. ## Distribute with your project
  430. The standard convention with client-server applications is to add an `npm start` command to launch the server component.
  431. 1\. Install the server as a dev dependency
  432. ```sh
  433. $ npm install local-web-server --save-dev
  434. ```
  435. 2\. Add a `start` command to your `package.json`:
  436. ```json
  437. {
  438. "name": "example",
  439. "version": "1.0.0",
  440. "local-web-server": {
  441. "port": 8100,
  442. "forbid": "*.json"
  443. },
  444. "scripts": {
  445. "start": "ws"
  446. }
  447. }
  448. ```
  449. 3\. Document how to build and launch your site
  450. ```sh
  451. $ npm install
  452. $ npm start
  453. serving at http://localhost:8100
  454. ```
  455. ## API Reference
  456. * [local-web-server](#module_local-web-server)
  457. * [localWebServer([options])](#exp_module_local-web-server--localWebServer) ⇒ <code>[KoaApplication](https://github.com/koajs/koa/blob/master/docs/api/index.md#application)</code>
  458. * [~rewriteRule](#module_local-web-server--localWebServer..rewriteRule)
  459. <a name="exp_module_local-web-server--localWebServer"></a>
  460. ### localWebServer([options]) ⇒ <code>[KoaApplication](https://github.com/koajs/koa/blob/master/docs/api/index.md#application)</code> ⏏
  461. Returns a Koa application you can launch or mix into an existing app.
  462. **Kind**: Exported function
  463. **Params**
  464. - [options] <code>object</code> - options
  465. - [.static] <code>object</code> - koa-static config
  466. - [.root] <code>string</code> <code> = &quot;.&quot;</code> - root directory
  467. - [.options] <code>string</code> - [options](https://github.com/koajs/static#options)
  468. - [.serveIndex] <code>object</code> - koa-serve-index config
  469. - [.path] <code>string</code> <code> = &quot;.&quot;</code> - root directory
  470. - [.options] <code>string</code> - [options](https://github.com/expressjs/serve-index#options)
  471. - [.forbid] <code>Array.&lt;string&gt;</code> - A list of forbidden routes, each route being an [express route-path](http://expressjs.com/guide/routing.html#route-paths).
  472. - [.spa] <code>string</code> - specify an SPA file to catch requests for everything but static assets.
  473. - [.log] <code>object</code> - [morgan](https://github.com/expressjs/morgan) config
  474. - [.format] <code>string</code> - [log format](https://github.com/expressjs/morgan#predefined-formats)
  475. - [.options] <code>object</code> - [options](https://github.com/expressjs/morgan#options)
  476. - [.compress] <code>boolean</code> - Serve gzip-compressed resources, where applicable
  477. - [.mime] <code>object</code> - A list of mime-type overrides, passed directly to [mime.define()](https://github.com/broofa/node-mime#mimedefine)
  478. - [.rewrite] <code>[Array.&lt;rewriteRule&gt;](#module_local-web-server--localWebServer..rewriteRule)</code> - One or more rewrite rules
  479. - [.verbose] <code>boolean</code> - Print detailed output, useful for debugging
  480. **Example**
  481. ```js
  482. const localWebServer = require('local-web-server')
  483. localWebServer().listen(8000)
  484. ```
  485. <a name="module_local-web-server--localWebServer..rewriteRule"></a>
  486. #### localWebServer~rewriteRule
  487. The `from` and `to` routes are specified using [express route-paths](http://expressjs.com/guide/routing.html#route-paths)
  488. **Kind**: inner typedef of <code>[localWebServer](#exp_module_local-web-server--localWebServer)</code>
  489. **Properties**
  490. | Name | Type | Description |
  491. | --- | --- | --- |
  492. | from | <code>string</code> | request route |
  493. | to | <code>string</code> | target route |
  494. **Example**
  495. ```json
  496. {
  497. "rewrite": [
  498. { "from": "/css/*", "to": "/build/styles/$1" },
  499. { "from": "/npm/*", "to": "http://registry.npmjs.org/$1" },
  500. { "from": "/:user/repos/:name", "to": "https://api.github.com/repos/:user/:name" }
  501. ]
  502. }
  503. ```
  504. * * *
  505. &copy; 2013-16 Lloyd Brookes <75pound@gmail.com>. Documented by [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown).