setupWriteToDisk.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. "use strict";
  2. const fs = require("fs");
  3. const path = require("path");
  4. /** @typedef {import("webpack").Compiler} Compiler */
  5. /** @typedef {import("webpack").MultiCompiler} MultiCompiler */
  6. /** @typedef {import("webpack").Compilation} Compilation */
  7. /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
  8. /** @typedef {import("../index.js").ServerResponse} ServerResponse */
  9. /**
  10. * @template {IncomingMessage} Request
  11. * @template {ServerResponse} Response
  12. * @param {import("../index.js").Context<Request, Response>} context
  13. */
  14. function setupWriteToDisk(context) {
  15. /**
  16. * @type {Compiler[]}
  17. */
  18. const compilers = /** @type {MultiCompiler} */
  19. context.compiler.compilers || [context.compiler];
  20. for (const compiler of compilers) {
  21. compiler.hooks.emit.tap("DevMiddleware", () => {
  22. // @ts-ignore
  23. if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) {
  24. return;
  25. }
  26. compiler.hooks.assetEmitted.tapAsync("DevMiddleware", (file, info, callback) => {
  27. const {
  28. targetPath,
  29. content
  30. } = info;
  31. const {
  32. writeToDisk: filter
  33. } = context.options;
  34. const allowWrite = filter && typeof filter === "function" ? filter(targetPath) : true;
  35. if (!allowWrite) {
  36. return callback();
  37. }
  38. const dir = path.dirname(targetPath);
  39. const name = compiler.options.name ? `Child "${compiler.options.name}": ` : "";
  40. return fs.mkdir(dir, {
  41. recursive: true
  42. }, mkdirError => {
  43. if (mkdirError) {
  44. context.logger.error(`${name}Unable to write "${dir}" directory to disk:\n${mkdirError}`);
  45. return callback(mkdirError);
  46. }
  47. return fs.writeFile(targetPath, content, writeFileError => {
  48. if (writeFileError) {
  49. context.logger.error(`${name}Unable to write "${targetPath}" asset to disk:\n${writeFileError}`);
  50. return callback(writeFileError);
  51. }
  52. context.logger.log(`${name}Asset written to disk: "${targetPath}"`);
  53. return callback();
  54. });
  55. });
  56. });
  57. // @ts-ignore
  58. compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true;
  59. });
  60. }
  61. }
  62. module.exports = setupWriteToDisk;