forked from KidkArolis/jetpack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
serve.js
85 lines (77 loc) Β· 2.42 KB
/
serve.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* handle node req/res
* and respond with client side app in both dev and prd!
* in dev β proxy to the jetpack dev server
* in prd β serve the static assets from dist
* handle all that jazz so you don't have to
*/
const fs = require('fs')
const { access } = require('fs-extra')
const path = require('path')
const send = require('send')
const http = require('http')
const parseUrl = require('parseurl')
const url = require('url')
const cli = require('./cli')
const options = cli.options()
const env = process.env.NODE_ENV || 'development'
module.exports =
env === 'development'
? createProxy(`http://localhost:${options.port}`)
: createServe(path.join(options.dir, options.dist))
function createProxy (target) {
return function proxy (req, res) {
return new Promise((resolve, reject) => {
const parsedTarget = url.parse(target)
const parsedReq = parseUrl(req)
const reqOpt = {
host: parsedTarget.hostname,
port: parsedTarget.port,
headers: req.headers,
method: req.method,
path: parsedReq.path,
params: req.params,
session: req.session
}
const proxyReq = http.request(reqOpt, function (proxyRes) {
proxyRes.pipe(res)
res.statusCode = proxyRes.statusCode
Object.keys(proxyRes.headers).forEach(header => res.setHeader(header, proxyRes.headers[header]))
})
proxyReq.on('error', function (err) {
if (err.code === 'ECONNREFUSED') {
const msg = `
Failed to connect to the jetpack dev server.
Make sure it's running by executing: jetpack
`
console.log(msg)
res.writeHead(502, { 'Content-Type': 'application/json' })
res.end(JSON.stringify({ error: msg }))
}
reject(err)
// TODO - reemit error?
})
proxyReq.on('end', function () {
resolve()
})
req.pipe(proxyReq)
})
}
}
function createServe (root) {
return async function serve (req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') return next()
let pathname = parseUrl(req).pathname
try {
await access(path.join(root, pathname), fs.constants.F_OK)
} catch (err) {
if (err.code === 'ENOENT') {
pathname = '/index.html'
}
}
const stream = send(req, pathname, { root })
stream.on('directory', () => next())
stream.on('error', err => next(err))
stream.pipe(res)
}
}