Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

99 rader
2.9 KiB

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