middleware.js
2.86 KB
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
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var mime = require("mime");
var getFilenameFromUrl = require("./lib/GetFilenameFromUrl");
var Shared = require("./lib/Shared");
var pathJoin = require("./lib/PathJoin");
// constructor for the middleware
module.exports = function(compiler, options) {
var context = {
state: false,
webpackStats: undefined,
callbacks: [],
options: options,
compiler: compiler,
watching: undefined,
forceRebuild: false
};
var shared = Shared(context);
// The middleware function
function webpackDevMiddleware(req, res, next) {
function goNext() {
if(!context.options.serverSideRender) return next();
return new Promise(function(resolve) {
shared.ready(function() {
res.locals.webpackStats = context.webpackStats;
resolve(next());
}, req);
});
}
if(req.method !== "GET") {
return goNext();
}
var filename = getFilenameFromUrl(context.options.publicPath, context.compiler, req.url);
if(filename === false) return goNext();
return new Promise(function(resolve) {
shared.handleRequest(filename, processRequest, req);
function processRequest() {
try {
var stat = context.fs.statSync(filename);
if(!stat.isFile()) {
if(stat.isDirectory()) {
var index = context.options.index;
if(index === undefined || index === true) {
index = "index.html";
} else if(!index) {
throw "next";
}
filename = pathJoin(filename, index);
stat = context.fs.statSync(filename);
if(!stat.isFile()) throw "next";
} else {
throw "next";
}
}
} catch(e) {
return resolve(goNext());
}
// server content
var content = context.fs.readFileSync(filename);
content = shared.handleRangeHeaders(content, req, res);
var contentType = mime.lookup(filename);
// do not add charset to WebAssembly files, otherwise compileStreaming will fail in the client
if(!/\.wasm$/.test(filename)) {
contentType += "; charset=UTF-8";
}
res.setHeader("Content-Type", contentType);
res.setHeader("Content-Length", content.length);
if(context.options.headers) {
for(var name in context.options.headers) {
res.setHeader(name, context.options.headers[name]);
}
}
// Express automatically sets the statusCode to 200, but not all servers do (Koa).
res.statusCode = res.statusCode || 200;
if(res.send) res.send(content);
else res.end(content);
resolve();
}
});
}
webpackDevMiddleware.getFilenameFromUrl = getFilenameFromUrl.bind(this, context.options.publicPath, context.compiler);
webpackDevMiddleware.waitUntilValid = shared.waitUntilValid;
webpackDevMiddleware.invalidate = shared.invalidate;
webpackDevMiddleware.close = shared.close;
webpackDevMiddleware.fileSystem = context.fs;
return webpackDevMiddleware;
};