UNPKG

2.92 kBJavaScriptView Raw
1'use strict';
2
3const mime = require('mime');
4const urlJoin = require('url-join');
5const { getFilenameFromUrl, handleRangeHeaders, handleRequest, ready } = require('./util');
6
7// mime 2.x is missing the .wasm update https://github.com/broofa/node-mime/issues/185
8mime.define({ 'application/wasm': ['wasm'] });
9
10module.exports = function wrapper(context) {
11 return function middleware(req, res, next) {
12 function goNext() {
13 if (!context.options.serverSideRender) {
14 return next();
15 }
16
17 return new Promise(((resolve) => {
18 ready(context, () => {
19 res.locals.webpackStats = context.webpackStats;
20 resolve(next());
21 }, req);
22 }));
23 }
24
25 if (req.method !== 'GET') {
26 return goNext();
27 }
28
29 let filename = getFilenameFromUrl(context.options.publicPath, context.compiler, req.url);
30
31 if (filename === false) {
32 return goNext();
33 }
34
35 return new Promise(((resolve) => {
36 handleRequest(context, filename, processRequest, req);
37 function processRequest() {
38 try {
39 let stat = context.fs.statSync(filename);
40 if (!stat.isFile()) {
41 if (stat.isDirectory()) {
42 let { index } = context.options;
43
44 if (index === undefined || index === true) {
45 index = 'index.html';
46 } else if (!index) {
47 // TODO throw a proper error
48 throw new Error('next');
49 }
50
51 filename = urlJoin(filename, index);
52 stat = context.fs.statSync(filename);
53 if (!stat.isFile()) {
54 // TODO throw a proper error
55 throw new Error('next');
56 }
57 } else {
58 // TODO throw a proper error
59 throw new Error('next');
60 }
61 }
62 } catch (e) {
63 return resolve(goNext());
64 }
65
66 // server content
67 let content = context.fs.readFileSync(filename);
68 content = handleRangeHeaders(content, req, res);
69 let contentType = mime.getType(filename);
70 // do not add charset to WebAssembly files, otherwise compileStreaming will fail in the client
71 if (!/\.wasm$/.test(filename)) {
72 contentType += '; charset=UTF-8';
73 }
74
75 res.setHeader('Content-Type', contentType);
76 res.setHeader('Content-Length', content.length);
77
78 const { headers } = context.options;
79 if (headers) {
80 for (const name in headers) {
81 if ({}.hasOwnProperty.call(headers, name)) {
82 res.setHeader(name, context.options.headers[name]);
83 }
84 }
85 }
86 // Express automatically sets the statusCode to 200, but not all servers do (Koa).
87 res.statusCode = res.statusCode || 200;
88 if (res.send) res.send(content);
89 else res.end(content);
90 resolve();
91 }
92 }));
93 };
94};