setupWriteToDisk.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. "use strict";
  2. const fs = require("node:fs");
  3. const path = require("node: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").WithOptional<import("../index.js").Context<Request, Response>, "watching" | "outputFileSystem">} context 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. if (compiler.options.devServer === false) {
  22. continue;
  23. }
  24. compiler.hooks.emit.tap("DevMiddleware", () => {
  25. // @ts-expect-error
  26. if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) {
  27. return;
  28. }
  29. compiler.hooks.assetEmitted.tapAsync("DevMiddleware", (file, info, callback) => {
  30. const {
  31. targetPath,
  32. content
  33. } = info;
  34. const {
  35. writeToDisk: filter
  36. } = context.options;
  37. const allowWrite = filter && typeof filter === "function" ? filter(targetPath) : true;
  38. if (!allowWrite) {
  39. return callback();
  40. }
  41. const dir = path.dirname(targetPath);
  42. const name = compiler.options.name ? `Child "${compiler.options.name}": ` : "";
  43. return fs.mkdir(dir, {
  44. recursive: true
  45. }, mkdirError => {
  46. if (mkdirError) {
  47. context.logger.error(`${name}Unable to write "${dir}" directory to disk:\n${mkdirError}`);
  48. return callback(mkdirError);
  49. }
  50. return fs.writeFile(targetPath, content, writeFileError => {
  51. if (writeFileError) {
  52. context.logger.error(`${name}Unable to write "${targetPath}" asset to disk:\n${writeFileError}`);
  53. return callback(writeFileError);
  54. }
  55. context.logger.log(`${name}Asset written to disk: "${targetPath}"`);
  56. return callback();
  57. });
  58. });
  59. });
  60. // @ts-expect-error
  61. compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true;
  62. });
  63. }
  64. }
  65. module.exports = setupWriteToDisk;