setupWriteToDisk.js 2.4 KB

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