forked from parcel-bundler/parcel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathServer.js
131 lines (114 loc) · 3.44 KB
/
Server.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const http = require('http');
const https = require('https');
const serveStatic = require('serve-static');
const getPort = require('get-port');
const serverErrors = require('./utils/customErrors').serverErrors;
const generateCertificate = require('./utils/generateCertificate');
const getCertificate = require('./utils/getCertificate');
const logger = require('./Logger');
const path = require('path');
const url = require('url');
serveStatic.mime.define({
'application/wasm': ['wasm']
});
function setHeaders(res) {
enableCors(res);
}
function enableCors(res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Methods',
'GET, HEAD, PUT, PATCH, POST, DELETE'
);
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Content-Type'
);
}
function middleware(bundler) {
const serve = serveStatic(bundler.options.outDir, {
index: false,
setHeaders: setHeaders
});
return function(req, res, next) {
// Wait for the bundler to finish bundling if needed
if (bundler.pending) {
bundler.once('bundled', respond);
} else {
respond();
}
function respond() {
let {pathname} = url.parse(req.url);
if (bundler.errored) {
return send500();
} else if (
!pathname.startsWith(bundler.options.publicURL) ||
path.extname(pathname) === ''
) {
// If the URL doesn't start with the public path, or the URL doesn't
// have a file extension, send the main HTML bundle.
return sendIndex();
} else {
// Otherwise, serve the file from the dist folder
req.url = pathname.slice(bundler.options.publicURL.length);
return serve(req, res, send404);
}
}
function sendIndex() {
// If the main asset is an HTML file, serve it
if (bundler.mainBundle.type === 'html') {
req.url = `/${path.basename(bundler.mainBundle.name)}`;
serve(req, res, send404);
} else {
send404();
}
}
function send500() {
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.writeHead(500);
res.end('🚨 Build error, check the console for details.');
}
function send404() {
if (next) {
return next();
}
res.writeHead(404);
res.end();
}
};
}
async function serve(bundler, port, useHTTPS = false) {
let handler = middleware(bundler);
let server;
if (!useHTTPS) {
server = http.createServer(handler);
} else if (typeof useHTTPS === 'boolean') {
server = https.createServer(generateCertificate(bundler.options), handler);
} else {
server = https.createServer(await getCertificate(useHTTPS), handler);
}
let freePort = await getPort({port});
server.listen(freePort);
return new Promise((resolve, reject) => {
server.on('error', err => {
logger.error(new Error(serverErrors(err, server.address().port)));
reject(err);
});
server.once('listening', () => {
let addon =
server.address().port !== port
? `- ${logger.chalk.yellow(
`configured port ${port} could not be used.`
)}`
: '';
logger.persistent(
`Server running at ${logger.chalk.cyan(
`${useHTTPS ? 'https' : 'http'}://localhost:${server.address().port}`
)} ${addon}`
);
resolve(server);
});
});
}
exports.middleware = middleware;
exports.serve = serve;