UNPKG

3.45 kBJavaScriptView Raw
1const http = require('http');
2const https = require('https');
3const serveStatic = require('serve-static');
4const getPort = require('get-port');
5const serverErrors = require('./utils/customErrors').serverErrors;
6const generateCertificate = require('./utils/generateCertificate');
7const getCertificate = require('./utils/getCertificate');
8const logger = require('./Logger');
9const path = require('path');
10
11serveStatic.mime.define({
12 'application/wasm': ['wasm']
13});
14
15function setHeaders(res) {
16 enableCors(res);
17}
18
19function enableCors(res) {
20 res.setHeader('Access-Control-Allow-Origin', '*');
21 res.setHeader(
22 'Access-Control-Allow-Methods',
23 'GET, HEAD, PUT, PATCH, POST, DELETE'
24 );
25 res.setHeader(
26 'Access-Control-Allow-Headers',
27 'Origin, X-Requested-With, Content-Type, Accept, Content-Type'
28 );
29}
30
31function middleware(bundler) {
32 const serve = serveStatic(bundler.options.outDir, {
33 index: false,
34 setHeaders: setHeaders
35 });
36
37 return function(req, res, next) {
38 // Wait for the bundler to finish bundling if needed
39 if (bundler.pending) {
40 bundler.once('bundled', respond);
41 } else {
42 respond();
43 }
44
45 function respond() {
46 if (bundler.errored) {
47 return send500();
48 } else if (
49 !req.url.startsWith(bundler.options.publicURL) ||
50 path.extname(req.url) === ''
51 ) {
52 // If the URL doesn't start with the public path, or the URL doesn't
53 // have a file extension, send the main HTML bundle.
54 return sendIndex();
55 } else {
56 // Otherwise, serve the file from the dist folder
57 req.url = req.url.slice(bundler.options.publicURL.length);
58 return serve(req, res, send404);
59 }
60 }
61
62 function sendIndex() {
63 // If the main asset is an HTML file, serve it
64 if (bundler.mainBundle.type === 'html') {
65 req.url = `/${path.basename(bundler.mainBundle.name)}`;
66 serve(req, res, send404);
67 } else {
68 send404();
69 }
70 }
71
72 function send500() {
73 res.setHeader('Content-Type', 'text/plain; charset=utf-8');
74 res.writeHead(500);
75 res.end('🚨 Build error, check the console for details.');
76 }
77
78 function send404() {
79 if (next) {
80 return next();
81 }
82
83 res.writeHead(404);
84 res.end();
85 }
86 };
87}
88
89async function serve(bundler, port, useHTTPS = false) {
90 let handler = middleware(bundler);
91 let server;
92 if (!useHTTPS) {
93 server = http.createServer(handler);
94 } else if (typeof useHTTPS === 'boolean') {
95 server = https.createServer(generateCertificate(bundler.options), handler);
96 } else {
97 server = https.createServer(await getCertificate(useHTTPS), handler);
98 }
99
100 let freePort = await getPort({port});
101 server.listen(freePort);
102
103 return new Promise((resolve, reject) => {
104 server.on('error', err => {
105 logger.error(new Error(serverErrors(err, server.address().port)));
106 reject(err);
107 });
108
109 server.once('listening', () => {
110 let addon =
111 server.address().port !== port
112 ? `- ${logger.chalk.yellow(
113 `configured port ${port} could not be used.`
114 )}`
115 : '';
116
117 logger.persistent(
118 `Server running at ${logger.chalk.cyan(
119 `${useHTTPS ? 'https' : 'http'}://localhost:${server.address().port}`
120 )} ${addon}`
121 );
122
123 resolve(server);
124 });
125 });
126}
127
128exports.middleware = middleware;
129exports.serve = serve;