1 | # sirv [![Build Status](https://travis-ci.org/lukeed/sirv.svg?branch=master)](https://travis-ci.org/lukeed/sirv)
|
2 |
|
3 | > The optimized and lightweight middleware for serving requests to static assets
|
4 |
|
5 | You may use `sirv` as a *very* fast and lightweight alternative to [`serve-static`](https://www.npmjs.com/package/serve-static). While (currently), `sirv` may not have the same options, it handles the majority of use cases without a hitch!
|
6 |
|
7 | The massive performance advantage over `serve-static` is explained by **not** relying on the file system for existence checks on every request. These are expensive interactions & must be avoided whenever possible! Instead, `sirv` performs all its work upfront and recycles the initial resultset for existence checks & writing header values based on files' stats.
|
8 |
|
9 | This middleware will work out of the box for [Polka](https://github.com/lukeed/polka) and other Express-like frameworks. It requires _very_ little effort to modify/wrap it for servers that don't accept the `(req, res, next)` signature.
|
10 |
|
11 | :bulb: For a feature-complete CLI application, check out the sibling [`sirv-cli`](https://github.com/lukeed/sirv/tree/master/packages/sirv-cli) package as an alternative to [`zeit/serve`](https://github.com/zeit/serve)~!
|
12 |
|
13 | ## Install
|
14 |
|
15 | ```
|
16 | $ npm install --save sirv
|
17 | ```
|
18 |
|
19 |
|
20 | ## Usage
|
21 |
|
22 | ```js
|
23 | const sirv = require('sirv');
|
24 | const polka = require('polka');
|
25 | const compress = require('compression')();
|
26 |
|
27 | // Init `sirv` handler
|
28 | const assets = sirv('public', {
|
29 | maxAge: 31536000, // 1Y
|
30 | immutable: true
|
31 | });
|
32 |
|
33 | polka()
|
34 | .use(compress, assets)
|
35 | .use('/api', require('./api'))
|
36 | .listen(3000)
|
37 | .then(() => {
|
38 | console.log('> Ready on localhost:3000~!');
|
39 | });
|
40 | ```
|
41 |
|
42 |
|
43 | ## API
|
44 |
|
45 | ### sirv(dir, opts={})
|
46 |
|
47 | Returns: `Function`
|
48 |
|
49 | The returned function is a middleware in the standard Express-like signature: `(req, res, next)`, where `req` is the [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage), `res` is the [`http.ServerResponse`](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_serverresponse), and `next` (in this case) is the function to call if no file was found for the given path.
|
50 |
|
51 | For `sirv`, the `next()` callback is functionally synonymous with [`opts.onNoMatch`](#optsonnomatch); however `next()` is given priority if/when defined and **will not** receive the `res` as an argument.
|
52 |
|
53 | #### dir
|
54 | Type: `String`<br>
|
55 | Default: `.`
|
56 |
|
57 | The directory from which to read and serve assets. It is resolved to an absolute path — you must provide an absolute path yourself if `process.cwd()` is not the correct assumption.
|
58 |
|
59 | #### opts.etag
|
60 | Type: `Boolean`<br>
|
61 | Default: `false`
|
62 |
|
63 | Generate and attach an `ETag` header to responses.
|
64 |
|
65 | #### opts.dotfiles
|
66 | Type: `Boolean`<br>
|
67 | Default: `false`
|
68 |
|
69 | Allow requests to dotfiles (files or directories beginning with a `.`).
|
70 |
|
71 | #### opts.extensions
|
72 | Type: `Array`<br>
|
73 | Default: `['html', 'htm']`
|
74 |
|
75 | The file extension fallbacks to check for if a pathame is not initially found. For example, if a `/login` request cannot find a `login` filename, it will then look for `login.html` and `login.htm` before giving up~!
|
76 |
|
77 | > **Important:** Actually, `sirv` will **also** look for `login/index.html` and `login/index.htm` before calling it quits.
|
78 |
|
79 | #### opts.maxAge
|
80 | Type: `Number`<br>
|
81 | Default: `undefined`
|
82 |
|
83 | Enables the `Cache-Control` header on responses & sets the `max-age` value (in seconds). For example `31536000` is equivalent to one year.
|
84 |
|
85 | #### opts.immutable
|
86 | Type: `Boolean`<br>
|
87 | Default: `false`
|
88 |
|
89 | Appends the [`immutable` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Revalidation_and_reloading) on your `Cache-Control` header, used for uniquely-named assets that will not change!
|
90 |
|
91 | > **Note:** Requires `opts.maxAge` to contain a value!
|
92 |
|
93 | #### opts.onNoMatch
|
94 | Type: `Function`
|
95 |
|
96 | A custom function to run if a file cannot be found for a given request. <br>By default, `sirv` will send a basic `(404) Not found` response.
|
97 |
|
98 | The function receives the current `res <ServerResponse>` as its only argument.
|
99 |
|
100 | > **Note:** This won't run if a `next` callback has been provided to the middleware; see [`sirv`](#sirvdir-opts) description.
|
101 |
|
102 | #### opts.setHeaders
|
103 | Type: `Function`
|
104 |
|
105 | A custom function to append or change any headers on the outgoing response. There is no default.
|
106 |
|
107 | Its signature is `(res, pathname, stats)`, where `res` is the `ServerResponse`, `pathname` is incoming request path (stripped of queries), and `stats` is the file's result from [`fs.statSync`](https://nodejs.org/api/fs.html#fs_fs_statsync_path).
|
108 |
|
109 |
|
110 | ## License
|
111 |
|
112 | MIT © [Luke Edwards](https://lukeed.com)
|