source: frontend/node_modules/webpack-dev-middleware/dist/index.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 7.6 KB
RevLine 
[9af201e]1"use strict";
2
3const {
4 validate
5} = require("schema-utils");
6
7const mime = require("mime-types");
8
9const middleware = require("./middleware");
10
11const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
12
13const setupHooks = require("./utils/setupHooks");
14
15const setupWriteToDisk = require("./utils/setupWriteToDisk");
16
17const setupOutputFileSystem = require("./utils/setupOutputFileSystem");
18
19const ready = require("./utils/ready");
20
21const schema = require("./options.json");
22
23const noop = () => {};
24/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */
25
26/** @typedef {import("webpack").Compiler} Compiler */
27
28/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
29
30/** @typedef {import("webpack").Configuration} Configuration */
31
32/** @typedef {import("webpack").Stats} Stats */
33
34/** @typedef {import("webpack").MultiStats} MultiStats */
35
36/**
37 * @typedef {Object} ExtendedServerResponse
38 * @property {{ webpack?: { devMiddleware?: Context<IncomingMessage, ServerResponse> } }} [locals]
39 */
40
41/** @typedef {import("http").IncomingMessage} IncomingMessage */
42
43/** @typedef {import("http").ServerResponse & ExtendedServerResponse} ServerResponse */
44
45/**
46 * @callback NextFunction
47 * @param {any} [err]
48 * @return {void}
49 */
50
51/**
52 * @typedef {NonNullable<Configuration["watchOptions"]>} WatchOptions
53 */
54
55/**
56 * @typedef {Compiler["watching"]} Watching
57 */
58
59/**
60 * @typedef {ReturnType<Compiler["watch"]>} MultiWatching
61 */
62
63/**
64 * @typedef {Compiler["outputFileSystem"] & { createReadStream?: import("fs").createReadStream, statSync?: import("fs").statSync, lstat?: import("fs").lstat, readFileSync?: import("fs").readFileSync }} OutputFileSystem
65 */
66
67/** @typedef {ReturnType<Compiler["getInfrastructureLogger"]>} Logger */
68
69/**
70 * @callback Callback
71 * @param {Stats | MultiStats} [stats]
72 */
73
74/**
75 * @template {IncomingMessage} Request
76 * @template {ServerResponse} Response
77 * @typedef {Object} Context
78 * @property {boolean} state
79 * @property {Stats | MultiStats | undefined} stats
80 * @property {Callback[]} callbacks
81 * @property {Options<Request, Response>} options
82 * @property {Compiler | MultiCompiler} compiler
83 * @property {Watching | MultiWatching} watching
84 * @property {Logger} logger
85 * @property {OutputFileSystem} outputFileSystem
86 */
87
88/**
89 * @template {IncomingMessage} Request
90 * @template {ServerResponse} Response
91 * @typedef {Record<string, string | number> | Array<{ key: string, value: number | string }> | ((req: Request, res: Response, context: Context<Request, Response>) => void | undefined | Record<string, string | number>) | undefined} Headers
92 */
93
94/**
95 * @template {IncomingMessage} Request
96 * @template {ServerResponse} Response
97 * @typedef {Object} Options
98 * @property {{[key: string]: string}} [mimeTypes]
99 * @property {boolean | ((targetPath: string) => boolean)} [writeToDisk]
100 * @property {string} [methods]
101 * @property {Headers<Request, Response>} [headers]
102 * @property {NonNullable<Configuration["output"]>["publicPath"]} [publicPath]
103 * @property {Configuration["stats"]} [stats]
104 * @property {boolean} [serverSideRender]
105 * @property {OutputFileSystem} [outputFileSystem]
106 * @property {boolean | string} [index]
107 */
108
109/**
110 * @template {IncomingMessage} Request
111 * @template {ServerResponse} Response
112 * @callback Middleware
113 * @param {Request} req
114 * @param {Response} res
115 * @param {NextFunction} next
116 * @return {Promise<void>}
117 */
118
119/**
120 * @callback GetFilenameFromUrl
121 * @param {string} url
122 * @returns {string | undefined}
123 */
124
125/**
126 * @callback WaitUntilValid
127 * @param {Callback} callback
128 */
129
130/**
131 * @callback Invalidate
132 * @param {Callback} callback
133 */
134
135/**
136 * @callback Close
137 * @param {(err: Error | null | undefined) => void} callback
138 */
139
140/**
141 * @template {IncomingMessage} Request
142 * @template {ServerResponse} Response
143 * @typedef {Object} AdditionalMethods
144 * @property {GetFilenameFromUrl} getFilenameFromUrl
145 * @property {WaitUntilValid} waitUntilValid
146 * @property {Invalidate} invalidate
147 * @property {Close} close
148 * @property {Context<Request, Response>} context
149 */
150
151/**
152 * @template {IncomingMessage} Request
153 * @template {ServerResponse} Response
154 * @typedef {Middleware<Request, Response> & AdditionalMethods<Request, Response>} API
155 */
156
157/**
158 * @template {IncomingMessage} Request
159 * @template {ServerResponse} Response
160 * @param {Compiler | MultiCompiler} compiler
161 * @param {Options<Request, Response>} [options]
162 * @returns {API<Request, Response>}
163 */
164
165
166function wdm(compiler, options = {}) {
167 validate(
168 /** @type {Schema} */
169 schema, options, {
170 name: "Dev Middleware",
171 baseDataPath: "options"
172 });
173 const {
174 mimeTypes
175 } = options;
176
177 if (mimeTypes) {
178 const {
179 types
180 } = mime; // mimeTypes from user provided options should take priority
181 // over existing, known types
182 // @ts-ignore
183
184 mime.types = { ...types,
185 ...mimeTypes
186 };
187 }
188 /**
189 * @type {Context<Request, Response>}
190 */
191
192
193 const context = {
194 state: false,
195 // eslint-disable-next-line no-undefined
196 stats: undefined,
197 callbacks: [],
198 options,
199 compiler,
200 // @ts-ignore
201 // eslint-disable-next-line no-undefined
202 watching: undefined,
203 logger: compiler.getInfrastructureLogger("webpack-dev-middleware"),
204 // @ts-ignore
205 // eslint-disable-next-line no-undefined
206 outputFileSystem: undefined
207 };
208 setupHooks(context);
209
210 if (options.writeToDisk) {
211 setupWriteToDisk(context);
212 }
213
214 setupOutputFileSystem(context); // Start watching
215
216 if (
217 /** @type {Compiler} */
218 context.compiler.watching) {
219 context.watching =
220 /** @type {Compiler} */
221 context.compiler.watching;
222 } else {
223 /**
224 * @type {WatchOptions | WatchOptions[]}
225 */
226 let watchOptions;
227 /**
228 * @param {Error | null | undefined} error
229 */
230
231 const errorHandler = error => {
232 if (error) {
233 // TODO: improve that in future
234 // For example - `writeToDisk` can throw an error and right now it is ends watching.
235 // We can improve that and keep watching active, but it is require API on webpack side.
236 // Let's implement that in webpack@5 because it is rare case.
237 context.logger.error(error);
238 }
239 };
240
241 if (Array.isArray(
242 /** @type {MultiCompiler} */
243 context.compiler.compilers)) {
244 watchOptions =
245 /** @type {MultiCompiler} */
246 context.compiler.compilers.map(
247 /**
248 * @param {Compiler} childCompiler
249 * @returns {WatchOptions}
250 */
251 childCompiler => childCompiler.options.watchOptions || {});
252 context.watching =
253 /** @type {MultiWatching} */
254 context.compiler.watch(
255 /** @type {WatchOptions}} */
256 watchOptions, errorHandler);
257 } else {
258 watchOptions =
259 /** @type {Compiler} */
260 context.compiler.options.watchOptions || {};
261 context.watching =
262 /** @type {Watching} */
263 context.compiler.watch(watchOptions, errorHandler);
264 }
265 }
266
267 const instance =
268 /** @type {API<Request, Response>} */
269 middleware(context); // API
270
271 /** @type {API<Request, Response>} */
272
273 instance.getFilenameFromUrl =
274 /**
275 * @param {string} url
276 * @returns {string|undefined}
277 */
278 url => getFilenameFromUrl(context, url);
279 /** @type {API<Request, Response>} */
280
281
282 instance.waitUntilValid = (callback = noop) => {
283 ready(context, callback);
284 };
285 /** @type {API<Request, Response>} */
286
287
288 instance.invalidate = (callback = noop) => {
289 ready(context, callback);
290 context.watching.invalidate();
291 };
292 /** @type {API<Request, Response>} */
293
294
295 instance.close = (callback = noop) => {
296 context.watching.close(callback);
297 };
298 /** @type {API<Request, Response>} */
299
300
301 instance.context = context;
302 return instance;
303}
304
305module.exports = wdm;
Note: See TracBrowser for help on using the repository browser.