middleware.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. var mime = require("mime");
  6. var getFilenameFromUrl = require("./lib/GetFilenameFromUrl");
  7. var Shared = require("./lib/Shared");
  8. var pathJoin = require("./lib/PathJoin");
  9. // constructor for the middleware
  10. module.exports = function(compiler, options) {
  11. var context = {
  12. state: false,
  13. webpackStats: undefined,
  14. callbacks: [],
  15. options: options,
  16. compiler: compiler,
  17. watching: undefined,
  18. forceRebuild: false
  19. };
  20. var shared = Shared(context);
  21. // The middleware function
  22. function webpackDevMiddleware(req, res, next) {
  23. function goNext() {
  24. if(!context.options.serverSideRender) return next();
  25. shared.ready(function() {
  26. res.locals.webpackStats = context.webpackStats;
  27. next();
  28. }, req);
  29. }
  30. if(req.method !== "GET") {
  31. return goNext();
  32. }
  33. var filename = getFilenameFromUrl(context.options.publicPath, context.compiler.outputPath, req.url);
  34. if(filename === false) return goNext();
  35. shared.handleRequest(filename, processRequest, req);
  36. function processRequest() {
  37. try {
  38. var stat = context.fs.statSync(filename);
  39. if(!stat.isFile()) {
  40. if(stat.isDirectory()) {
  41. filename = pathJoin(filename, context.options.index || "index.html");
  42. stat = context.fs.statSync(filename);
  43. if(!stat.isFile()) throw "next";
  44. } else {
  45. throw "next";
  46. }
  47. }
  48. } catch(e) {
  49. return goNext();
  50. }
  51. // server content
  52. var content = context.fs.readFileSync(filename);
  53. content = shared.handleRangeHeaders(content, req, res);
  54. res.setHeader("Access-Control-Allow-Origin", "*"); // To support XHR, etc.
  55. res.setHeader("Content-Type", mime.lookup(filename) + "; charset=UTF-8");
  56. res.setHeader("Content-Length", content.length);
  57. if(context.options.headers) {
  58. for(var name in context.options.headers) {
  59. res.setHeader(name, context.options.headers[name]);
  60. }
  61. }
  62. // Express automatically sets the statusCode to 200, but not all servers do (Koa).
  63. res.statusCode = res.statusCode || 200;
  64. if(res.send) res.send(content);
  65. else res.end(content);
  66. }
  67. }
  68. webpackDevMiddleware.getFilenameFromUrl = getFilenameFromUrl.bind(this, context.options.publicPath, context.compiler.outputPath);
  69. webpackDevMiddleware.waitUntilValid = shared.waitUntilValid;
  70. webpackDevMiddleware.invalidate = shared.invalidate;
  71. webpackDevMiddleware.close = shared.close;
  72. webpackDevMiddleware.fileSystem = context.fs;
  73. return webpackDevMiddleware;
  74. };