UNPKG

5.09 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
6
7const http = require('http');
8
9const https = require('https');
10
11const serveStatic = require('serve-static');
12
13const getPort = require('get-port');
14
15const serverErrors = require('./utils/customErrors').serverErrors;
16
17const generateCertificate = require('./utils/generateCertificate');
18
19const getCertificate = require('./utils/getCertificate');
20
21const AnsiToHtml = require('ansi-to-html');
22
23const logger = require('@parcel/logger');
24
25const path = require('path');
26
27const url = require('url');
28
29const ansiToHtml = new AnsiToHtml({
30 newline: true
31});
32serveStatic.mime.define({
33 'application/wasm': ['wasm']
34});
35
36function setHeaders(res) {
37 enableCors(res);
38}
39
40function enableCors(res) {
41 res.setHeader('Access-Control-Allow-Origin', '*');
42 res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, PUT, PATCH, POST, DELETE');
43 res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Content-Type');
44}
45
46function middleware(bundler) {
47 const serve = serveStatic(bundler.options.outDir, {
48 index: false,
49 redirect: false,
50 setHeaders: setHeaders,
51 dotfiles: 'allow'
52 });
53 return function (req, res, next) {
54 logAccessIfVerbose(); // Wait for the bundler to finish bundling if needed
55
56 if (bundler.pending) {
57 bundler.once('bundled', respond);
58 } else {
59 respond();
60 }
61
62 function respond() {
63 let _url$parse = url.parse(req.url),
64 pathname = _url$parse.pathname;
65
66 if (bundler.error) {
67 return send500(bundler.error);
68 } else if (!pathname.startsWith(bundler.options.publicURL) || path.extname(pathname) === '') {
69 // If the URL doesn't start with the public path, or the URL doesn't
70 // have a file extension, send the main HTML bundle.
71 return sendIndex();
72 } else {
73 // Otherwise, serve the file from the dist folder
74 req.url = pathname.slice(bundler.options.publicURL.length);
75 return serve(req, res, sendIndex);
76 }
77 }
78
79 function sendIndex() {
80 // If the main asset is an HTML file, serve it
81 if (bundler.mainBundle.type === 'html') {
82 req.url = `/${path.basename(bundler.mainBundle.name)}`;
83 serve(req, res, send404);
84 } else {
85 send404();
86 }
87 }
88
89 function send500(error) {
90 setHeaders(res);
91 res.setHeader('Content-Type', 'text/html; charset=utf-8');
92 res.writeHead(500);
93 let errorMesssge = '<h1>🚨 Build Error</h1>';
94
95 if (process.env.NODE_ENV === 'production') {
96 errorMesssge += '<p><b>Check the console for details.</b></p>';
97 } else {
98 const _logger$formatError = logger.formatError(error, {
99 color: true
100 }),
101 message = _logger$formatError.message,
102 stack = _logger$formatError.stack;
103
104 errorMesssge += `<p><b>${message}</b></p>`;
105
106 if (stack) {
107 errorMesssge += `<div style="background: black; padding: 1rem;">${ansiToHtml.toHtml(stack)}</div>`;
108 }
109 }
110
111 res.end([`<!doctype html>`, `<head><title>🚨 Build Error</title></head>`, `<body style="font-family: monospace; white-space: pre;">${errorMesssge}</body>`].join(''));
112 }
113
114 function send404() {
115 if (next) {
116 return next();
117 }
118
119 setHeaders(res);
120 res.writeHead(404);
121 res.end();
122 }
123
124 function logAccessIfVerbose() {
125 const protocol = req.connection.encrypted ? 'https' : 'http';
126 const fullUrl = `${protocol}://${req.headers.host}${req.url}`;
127 logger.verbose(`Request: ${fullUrl}`);
128 }
129 };
130}
131
132function serve(_x, _x2, _x3) {
133 return _serve.apply(this, arguments);
134}
135
136function _serve() {
137 _serve = (0, _asyncToGenerator2.default)(function* (bundler, port, host, useHTTPS = false) {
138 let handler = middleware(bundler);
139 let server;
140
141 if (!useHTTPS) {
142 server = http.createServer(handler);
143 } else if (typeof useHTTPS === 'boolean') {
144 server = https.createServer(generateCertificate(bundler.options), handler);
145 } else {
146 server = https.createServer((yield getCertificate(useHTTPS)), handler);
147 }
148
149 let freePort = yield getPort({
150 port
151 });
152 server.listen(freePort, host);
153 return new Promise((resolve, reject) => {
154 server.on('error', err => {
155 console.log(err);
156 logger.error(new Error(serverErrors(err, server.address().port)));
157 reject(err);
158 });
159 server.once('listening', () => {
160 let addon = server.address().port !== port ? `- ${logger.chalk.yellow(`configured port ${port} could not be used.`)}` : '';
161 logger.persistent(`Server running at ${logger.chalk.cyan(`${useHTTPS ? 'https' : 'http'}://${host || 'localhost'}:${server.address().port}`)} ${addon}`);
162 resolve(server);
163 });
164 });
165 });
166 return _serve.apply(this, arguments);
167}
168
169exports.middleware = middleware;
170exports.serve = serve;
\No newline at end of file