Skip to content

Commit d2f0731

Browse files
committed
Refactor to sirv
Use prettier Resolve #42 as sirv supports Range
1 parent 0e17e03 commit d2f0731

File tree

5 files changed

+175
-1470
lines changed

5 files changed

+175
-1470
lines changed

package.json

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"scripts": {
99
"build": "rollup -c",
1010
"dev": "rollup -cw",
11-
"lint": "standard --fix rollup.config.js src/**",
11+
"lint": "prettier --write rollup.config.js src/**",
1212
"prepare": "yarn lint && yarn build",
1313
"test": "cd test && rollup -c || cd .."
1414
},
@@ -32,13 +32,24 @@
3232
"files": [
3333
"dist"
3434
],
35-
"dependencies": {
36-
"mime": ">=2.0.3",
37-
"opener": "1"
38-
},
3935
"devDependencies": {
36+
"connect-compose": "0.0.1",
37+
"opener": "1",
38+
"prettier": "^1.19.1",
4039
"rollup": "1",
4140
"rollup-plugin-buble": "^0.15.0",
42-
"standard": "14"
41+
"rollup-plugin-commonjs": "^10.1.0",
42+
"rollup-plugin-node-resolve": "^5.2.0",
43+
"sirv": "^0.4.2"
44+
},
45+
"prettier": {
46+
"trailingComma": "none",
47+
"semi": false,
48+
"singleQuote": true
49+
},
50+
"husky": {
51+
"hooks": {
52+
"pre-commit": "pretty-quick --pattern \"**/*.(js|html)\" --staged"
53+
}
4354
}
4455
}

rollup.config.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import buble from 'rollup-plugin-buble'
2+
import resolve from 'rollup-plugin-node-resolve'
3+
import commonjs from 'rollup-plugin-commonjs'
24

35
export default {
46
input: 'src/index.js',
57
output: [
68
{ file: 'dist/index.cjs.js', format: 'cjs' },
79
{ file: 'dist/index.es.js', format: 'esm' }
810
],
9-
plugins: [buble()],
10-
onwarn ({ code, message }) {
11-
if (code !== 'UNRESOLVED_IMPORT') {
12-
console.warn(message)
13-
}
14-
}
11+
plugins: [commonjs(), resolve(), buble()],
12+
external: [].concat(
13+
require('module').builtinModules || Object.keys(process.binding('natives'))
14+
)
1515
}

src/index.js

Lines changed: 66 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,95 @@
1-
import { readFile } from 'fs'
21
import { createServer as createHttpsServer } from 'https'
32
import { createServer } from 'http'
43
import { resolve } from 'path'
54

6-
import mime from 'mime'
75
import opener from 'opener'
6+
import sirv from 'sirv'
7+
import compose from 'connect-compose'
88

99
let server
1010

1111
/**
1212
* Serve your rolled up bundle like webpack-dev-server
1313
* @param {ServeOptions|string|string[]} options
1414
*/
15-
function serve (options = { contentBase: '' }) {
15+
export default function serve(options = { contentBase: '' }) {
1616
if (Array.isArray(options) || typeof options === 'string') {
1717
options = { contentBase: options }
1818
}
19-
options.contentBase = Array.isArray(options.contentBase) ? options.contentBase : [options.contentBase || '']
19+
options.contentBase = Array.isArray(options.contentBase)
20+
? options.contentBase
21+
: [options.contentBase || '']
2022
options.port = options.port || 10001
2123
options.headers = options.headers || {}
2224
options.https = options.https || false
2325
options.openPage = options.openPage || ''
24-
mime.default_type = 'text/plain'
2526

26-
const requestListener = (request, response) => {
27-
// Remove querystring
28-
const urlPath = decodeURI(request.url.split('?')[0])
29-
30-
Object.keys(options.headers).forEach((key) => {
31-
response.setHeader(key, options.headers[key])
32-
})
33-
34-
readFileFromContentBase(options.contentBase, urlPath, function (error, content, filePath) {
35-
if (!error) {
36-
return found(response, filePath, content)
37-
}
38-
if (error.code !== 'ENOENT') {
39-
response.writeHead(500)
40-
response.end('500 Internal Server Error' +
41-
'\n\n' + filePath +
42-
'\n\n' + Object.values(error).join('\n') +
43-
'\n\n(rollup-plugin-serve)', 'utf-8')
44-
return
45-
}
46-
if (options.historyApiFallback) {
47-
const fallbackPath = typeof options.historyApiFallback === 'string' ? options.historyApiFallback : '/index.html'
48-
readFileFromContentBase(options.contentBase, fallbackPath, function (error, content, filePath) {
49-
if (error) {
50-
notFound(response, filePath)
51-
} else {
52-
found(response, filePath, content)
53-
}
54-
})
55-
} else {
56-
notFound(response, filePath)
57-
}
58-
})
59-
}
60-
61-
// release previous server instance if rollup is reloading configuration in watch mode
27+
// Release previous server instance if rollup is reloading configuration in watch mode
6228
if (server) {
6329
server.close()
6430
} else {
6531
closeServerOnTermination()
6632
}
6733

34+
// Serve all folders
35+
const middlewares = options.contentBase.map(base => sirv(base, { dev: true }))
36+
37+
// Send custom headers
38+
if (options.headers) {
39+
middlewares.unshift(setHeaders)
40+
}
41+
42+
// Fallback to another page
43+
let { historyApiFallback: fallback } = options
44+
if (fallback) {
45+
// Defaults to index.html, sirv know where to look
46+
fallback = typeof fallback === 'string' ? fallback : '/'
47+
48+
// Must start with /
49+
fallback = (fallback.startsWith('/') ? '' : '/') + fallback
50+
51+
// Swap out the requested page with the fallback page
52+
middlewares.push((req, res, next) => {
53+
req.originalUrl = req.url
54+
req.url = fallback
55+
next()
56+
})
57+
58+
// Serve the static files again, this time looking for the fallback page
59+
const serveStatic = middlewares.slice(-3, -1)
60+
serveStatic.forEach(middleware => middlewares.push(middleware))
61+
}
62+
63+
middlewares.push(errorPage)
64+
65+
// Combine all middlewares into one
66+
const app = compose(middlewares)
67+
6868
// If HTTPS options are available, create an HTTPS server
6969
if (options.https) {
70-
server = createHttpsServer(options.https, requestListener).listen(options.port, options.host)
70+
server = createHttpsServer(options.https, app).listen(
71+
options.port,
72+
options.host
73+
)
7174
} else {
72-
server = createServer(requestListener).listen(options.port, options.host)
75+
server = createServer(app).listen(options.port, options.host)
7376
}
7477

7578
let running = options.verbose === false
7679

7780
return {
7881
name: 'serve',
79-
generateBundle () {
82+
generateBundle() {
8083
if (!running) {
8184
running = true
8285

8386
// Log which url to visit
84-
const url = (options.https ? 'https' : 'http') + '://' + (options.host || 'localhost') + ':' + options.port
87+
const url =
88+
(options.https ? 'https' : 'http') +
89+
'://' +
90+
(options.host || 'localhost') +
91+
':' +
92+
options.port
8593
options.contentBase.forEach(base => {
8694
console.log(green(url) + ' -> ' + resolve(base))
8795
})
@@ -97,40 +105,24 @@ function serve (options = { contentBase: '' }) {
97105
}
98106
}
99107
}
100-
}
101108

102-
function readFileFromContentBase (contentBase, urlPath, callback) {
103-
let filePath = resolve(contentBase[0] || '.', '.' + urlPath)
104-
105-
// Load index.html in directories
106-
if (urlPath.endsWith('/')) {
107-
filePath = resolve(filePath, 'index.html')
109+
function setHeaders(req, res, next) {
110+
Object.keys(options.headers).forEach(key => {
111+
res.setHeader(key, options.headers[key])
112+
})
113+
next()
108114
}
109115

110-
readFile(filePath, (error, content) => {
111-
if (error && contentBase.length > 1) {
112-
// Try to read from next contentBase
113-
readFileFromContentBase(contentBase.slice(1), urlPath, callback)
114-
} else {
115-
// We know enough
116-
callback(error, content, filePath)
117-
}
118-
})
119-
}
120-
121-
function notFound (response, filePath) {
122-
response.writeHead(404)
123-
response.end('404 Not Found' +
124-
'\n\n' + filePath +
125-
'\n\n(rollup-plugin-serve)', 'utf-8')
126-
}
127-
128-
function found (response, filePath, content) {
129-
response.writeHead(200, { 'Content-Type': mime.getType(filePath) })
130-
response.end(content, 'utf-8')
116+
function errorPage(req, res) {
117+
res.writeHead(404)
118+
res.end(
119+
'404 Not Found' + '\n\n' + req.originalUrl + '\n\n(rollup-plugin-serve)',
120+
'utf-8'
121+
)
122+
}
131123
}
132124

133-
function green (text) {
125+
function green(text) {
134126
return '\u001b[1m\u001b[32m' + text + '\u001b[39m\u001b[22m'
135127
}
136128

@@ -146,8 +138,6 @@ function closeServerOnTermination() {
146138
})
147139
}
148140

149-
export default serve
150-
151141
/**
152142
* @typedef {Object} ServeOptions
153143
* @property {boolean} [open=false] Launch in browser (default: `false`)

test/rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import serve from '..'
1+
import serve from '../dist/index.es'
22

33
export default {
44
input: 'entry.js',

0 commit comments

Comments
 (0)