Updated the files.
This commit is contained in:
parent
1553e6b971
commit
753967d4f5
23418 changed files with 3784666 additions and 0 deletions
287
my-app/node_modules/webpack-dev-middleware/dist/index.js
generated
vendored
Executable file
287
my-app/node_modules/webpack-dev-middleware/dist/index.js
generated
vendored
Executable file
|
@ -0,0 +1,287 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
validate
|
||||
} = require("schema-utils");
|
||||
const mime = require("mime-types");
|
||||
const middleware = require("./middleware");
|
||||
const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
|
||||
const setupHooks = require("./utils/setupHooks");
|
||||
const setupWriteToDisk = require("./utils/setupWriteToDisk");
|
||||
const setupOutputFileSystem = require("./utils/setupOutputFileSystem");
|
||||
const ready = require("./utils/ready");
|
||||
const schema = require("./options.json");
|
||||
const noop = () => {};
|
||||
|
||||
/** @typedef {import("schema-utils/declarations/validate").Schema} Schema */
|
||||
/** @typedef {import("webpack").Compiler} Compiler */
|
||||
/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
|
||||
/** @typedef {import("webpack").Configuration} Configuration */
|
||||
/** @typedef {import("webpack").Stats} Stats */
|
||||
/** @typedef {import("webpack").MultiStats} MultiStats */
|
||||
/** @typedef {import("fs").ReadStream} ReadStream */
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExtendedServerResponse
|
||||
* @property {{ webpack?: { devMiddleware?: Context<IncomingMessage, ServerResponse> } }} [locals]
|
||||
*/
|
||||
|
||||
/** @typedef {import("http").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("http").ServerResponse & ExtendedServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @callback NextFunction
|
||||
* @param {any} [err]
|
||||
* @return {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {NonNullable<Configuration["watchOptions"]>} WatchOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Compiler["watching"]} Watching
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ReturnType<Compiler["watch"]>} MultiWatching
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Compiler["outputFileSystem"] & { createReadStream?: import("fs").createReadStream, statSync?: import("fs").statSync, lstat?: import("fs").lstat, readFileSync?: import("fs").readFileSync }} OutputFileSystem
|
||||
*/
|
||||
|
||||
/** @typedef {ReturnType<Compiler["getInfrastructureLogger"]>} Logger */
|
||||
|
||||
/**
|
||||
* @callback Callback
|
||||
* @param {Stats | MultiStats} [stats]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ResponseData
|
||||
* @property {string | Buffer | ReadStream} data
|
||||
* @property {number} byteLength
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @callback ModifyResponseData
|
||||
* @param {RequestInternal} req
|
||||
* @param {ResponseInternal} res
|
||||
* @param {string | Buffer | ReadStream} data
|
||||
* @param {number} byteLength
|
||||
* @return {ResponseData}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @typedef {Object} Context
|
||||
* @property {boolean} state
|
||||
* @property {Stats | MultiStats | undefined} stats
|
||||
* @property {Callback[]} callbacks
|
||||
* @property {Options<RequestInternal, ResponseInternal>} options
|
||||
* @property {Compiler | MultiCompiler} compiler
|
||||
* @property {Watching | MultiWatching} watching
|
||||
* @property {Logger} logger
|
||||
* @property {OutputFileSystem} outputFileSystem
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @typedef {Record<string, string | number> | Array<{ key: string, value: number | string }> | ((req: RequestInternal, res: ResponseInternal, context: Context<RequestInternal, ResponseInternal>) => void | undefined | Record<string, string | number>) | undefined} Headers
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @typedef {Object} Options
|
||||
* @property {{[key: string]: string}} [mimeTypes]
|
||||
* @property {string | undefined} [mimeTypeDefault]
|
||||
* @property {boolean | ((targetPath: string) => boolean)} [writeToDisk]
|
||||
* @property {string[]} [methods]
|
||||
* @property {Headers<RequestInternal, ResponseInternal>} [headers]
|
||||
* @property {NonNullable<Configuration["output"]>["publicPath"]} [publicPath]
|
||||
* @property {Configuration["stats"]} [stats]
|
||||
* @property {boolean} [serverSideRender]
|
||||
* @property {OutputFileSystem} [outputFileSystem]
|
||||
* @property {boolean | string} [index]
|
||||
* @property {ModifyResponseData<RequestInternal, ResponseInternal>} [modifyResponseData]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @callback Middleware
|
||||
* @param {RequestInternal} req
|
||||
* @param {ResponseInternal} res
|
||||
* @param {NextFunction} next
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback GetFilenameFromUrl
|
||||
* @param {string} url
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback WaitUntilValid
|
||||
* @param {Callback} callback
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback Invalidate
|
||||
* @param {Callback} callback
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback Close
|
||||
* @param {(err: Error | null | undefined) => void} callback
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @typedef {Object} AdditionalMethods
|
||||
* @property {GetFilenameFromUrl} getFilenameFromUrl
|
||||
* @property {WaitUntilValid} waitUntilValid
|
||||
* @property {Invalidate} invalidate
|
||||
* @property {Close} close
|
||||
* @property {Context<RequestInternal, ResponseInternal>} context
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @typedef {Middleware<RequestInternal, ResponseInternal> & AdditionalMethods<RequestInternal, ResponseInternal>} API
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} RequestInternal
|
||||
* @template {ServerResponse} ResponseInternal
|
||||
* @param {Compiler | MultiCompiler} compiler
|
||||
* @param {Options<RequestInternal, ResponseInternal>} [options]
|
||||
* @returns {API<RequestInternal, ResponseInternal>}
|
||||
*/
|
||||
function wdm(compiler, options = {}) {
|
||||
validate( /** @type {Schema} */schema, options, {
|
||||
name: "Dev Middleware",
|
||||
baseDataPath: "options"
|
||||
});
|
||||
const {
|
||||
mimeTypes
|
||||
} = options;
|
||||
if (mimeTypes) {
|
||||
const {
|
||||
types
|
||||
} = mime;
|
||||
|
||||
// mimeTypes from user provided options should take priority
|
||||
// over existing, known types
|
||||
// @ts-ignore
|
||||
mime.types = {
|
||||
...types,
|
||||
...mimeTypes
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Context<RequestInternal, ResponseInternal>}
|
||||
*/
|
||||
const context = {
|
||||
state: false,
|
||||
// eslint-disable-next-line no-undefined
|
||||
stats: undefined,
|
||||
callbacks: [],
|
||||
options,
|
||||
compiler,
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undefined
|
||||
watching: undefined,
|
||||
logger: compiler.getInfrastructureLogger("webpack-dev-middleware"),
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undefined
|
||||
outputFileSystem: undefined
|
||||
};
|
||||
setupHooks(context);
|
||||
if (options.writeToDisk) {
|
||||
setupWriteToDisk(context);
|
||||
}
|
||||
setupOutputFileSystem(context);
|
||||
|
||||
// Start watching
|
||||
if ( /** @type {Compiler} */context.compiler.watching) {
|
||||
context.watching = /** @type {Compiler} */context.compiler.watching;
|
||||
} else {
|
||||
/**
|
||||
* @type {WatchOptions | WatchOptions[]}
|
||||
*/
|
||||
let watchOptions;
|
||||
|
||||
/**
|
||||
* @param {Error | null | undefined} error
|
||||
*/
|
||||
const errorHandler = error => {
|
||||
if (error) {
|
||||
// TODO: improve that in future
|
||||
// For example - `writeToDisk` can throw an error and right now it is ends watching.
|
||||
// We can improve that and keep watching active, but it is require API on webpack side.
|
||||
// Let's implement that in webpack@5 because it is rare case.
|
||||
context.logger.error(error);
|
||||
}
|
||||
};
|
||||
if (Array.isArray( /** @type {MultiCompiler} */context.compiler.compilers)) {
|
||||
watchOptions = /** @type {MultiCompiler} */
|
||||
context.compiler.compilers.map(
|
||||
/**
|
||||
* @param {Compiler} childCompiler
|
||||
* @returns {WatchOptions}
|
||||
*/
|
||||
childCompiler => childCompiler.options.watchOptions || {});
|
||||
context.watching = /** @type {MultiWatching} */
|
||||
|
||||
context.compiler.watch( /** @type {WatchOptions}} */
|
||||
watchOptions, errorHandler);
|
||||
} else {
|
||||
watchOptions = /** @type {Compiler} */context.compiler.options.watchOptions || {};
|
||||
context.watching = /** @type {Watching} */
|
||||
context.compiler.watch(watchOptions, errorHandler);
|
||||
}
|
||||
}
|
||||
const instance = /** @type {API<RequestInternal, ResponseInternal>} */
|
||||
middleware(context);
|
||||
|
||||
// API
|
||||
/** @type {API<RequestInternal, ResponseInternal>} */
|
||||
instance.getFilenameFromUrl =
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns {string|undefined}
|
||||
*/
|
||||
url => getFilenameFromUrl(context, url);
|
||||
|
||||
/** @type {API<RequestInternal, ResponseInternal>} */
|
||||
instance.waitUntilValid = (callback = noop) => {
|
||||
ready(context, callback);
|
||||
};
|
||||
|
||||
/** @type {API<RequestInternal, ResponseInternal>} */
|
||||
instance.invalidate = (callback = noop) => {
|
||||
ready(context, callback);
|
||||
context.watching.invalidate();
|
||||
};
|
||||
|
||||
/** @type {API<RequestInternal, ResponseInternal>} */
|
||||
instance.close = (callback = noop) => {
|
||||
context.watching.close(callback);
|
||||
};
|
||||
|
||||
/** @type {API<RequestInternal, ResponseInternal>} */
|
||||
instance.context = context;
|
||||
return instance;
|
||||
}
|
||||
module.exports = wdm;
|
214
my-app/node_modules/webpack-dev-middleware/dist/middleware.js
generated
vendored
Executable file
214
my-app/node_modules/webpack-dev-middleware/dist/middleware.js
generated
vendored
Executable file
|
@ -0,0 +1,214 @@
|
|||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const mime = require("mime-types");
|
||||
const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
|
||||
const {
|
||||
getHeaderNames,
|
||||
getHeaderFromRequest,
|
||||
getHeaderFromResponse,
|
||||
setHeaderForResponse,
|
||||
setStatusCode,
|
||||
send
|
||||
} = require("./utils/compatibleAPI");
|
||||
const ready = require("./utils/ready");
|
||||
|
||||
/** @typedef {import("./index.js").NextFunction} NextFunction */
|
||||
/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("./index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @param {string} type
|
||||
* @param {number} size
|
||||
* @param {import("range-parser").Range} [range]
|
||||
* @returns {string}
|
||||
*/
|
||||
function getValueContentRangeHeader(type, size, range) {
|
||||
return `${type} ${range ? `${range.start}-${range.end}` : "*"}/${size}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | number} title
|
||||
* @param {string} body
|
||||
* @returns {string}
|
||||
*/
|
||||
function createHtmlDocument(title, body) {
|
||||
return `${"<!DOCTYPE html>\n" + '<html lang="en">\n' + "<head>\n" + '<meta charset="utf-8">\n' + "<title>"}${title}</title>\n` + `</head>\n` + `<body>\n` + `<pre>${body}</pre>\n` + `</body>\n` + `</html>\n`;
|
||||
}
|
||||
const BYTES_RANGE_REGEXP = /^ *bytes/i;
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("./index.js").Context<Request, Response>} context
|
||||
* @return {import("./index.js").Middleware<Request, Response>}
|
||||
*/
|
||||
function wrapper(context) {
|
||||
return async function middleware(req, res, next) {
|
||||
const acceptedMethods = context.options.methods || ["GET", "HEAD"];
|
||||
|
||||
// fixes #282. credit @cexoso. in certain edge situations res.locals is undefined.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.locals = res.locals || {};
|
||||
if (req.method && !acceptedMethods.includes(req.method)) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
ready(context, processRequest, req);
|
||||
async function goNext() {
|
||||
if (!context.options.serverSideRender) {
|
||||
return next();
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
ready(context, () => {
|
||||
/** @type {any} */
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.locals.webpack = {
|
||||
devMiddleware: context
|
||||
};
|
||||
resolve(next());
|
||||
}, req);
|
||||
});
|
||||
}
|
||||
async function processRequest() {
|
||||
const filename = getFilenameFromUrl(context, /** @type {string} */req.url);
|
||||
if (!filename) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
let {
|
||||
headers
|
||||
} = context.options;
|
||||
if (typeof headers === "function") {
|
||||
// @ts-ignore
|
||||
headers = headers(req, res, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {{key: string, value: string | number}[]}
|
||||
*/
|
||||
const allHeaders = [];
|
||||
if (typeof headers !== "undefined") {
|
||||
if (!Array.isArray(headers)) {
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (const name in headers) {
|
||||
// @ts-ignore
|
||||
allHeaders.push({
|
||||
key: name,
|
||||
value: headers[name]
|
||||
});
|
||||
}
|
||||
headers = allHeaders;
|
||||
}
|
||||
headers.forEach(
|
||||
/**
|
||||
* @param {{key: string, value: any}} header
|
||||
*/
|
||||
header => {
|
||||
setHeaderForResponse(res, header.key, header.value);
|
||||
});
|
||||
}
|
||||
if (!getHeaderFromResponse(res, "Content-Type")) {
|
||||
// content-type name(like application/javascript; charset=utf-8) or false
|
||||
const contentType = mime.contentType(path.extname(filename));
|
||||
|
||||
// Only set content-type header if media type is known
|
||||
// https://tools.ietf.org/html/rfc7231#section-3.1.1.5
|
||||
if (contentType) {
|
||||
setHeaderForResponse(res, "Content-Type", contentType);
|
||||
} else if (context.options.mimeTypeDefault) {
|
||||
setHeaderForResponse(res, "Content-Type", context.options.mimeTypeDefault);
|
||||
}
|
||||
}
|
||||
if (!getHeaderFromResponse(res, "Accept-Ranges")) {
|
||||
setHeaderForResponse(res, "Accept-Ranges", "bytes");
|
||||
}
|
||||
const rangeHeader = getHeaderFromRequest(req, "range");
|
||||
let start;
|
||||
let end;
|
||||
if (rangeHeader && BYTES_RANGE_REGEXP.test(rangeHeader)) {
|
||||
const size = await new Promise(resolve => {
|
||||
/** @type {import("fs").lstat} */
|
||||
context.outputFileSystem.lstat(filename, (error, stats) => {
|
||||
if (error) {
|
||||
context.logger.error(error);
|
||||
return;
|
||||
}
|
||||
resolve(stats.size);
|
||||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line global-require
|
||||
const parsedRanges = require("range-parser")(size, rangeHeader, {
|
||||
combine: true
|
||||
});
|
||||
if (parsedRanges === -1) {
|
||||
const message = "Unsatisfiable range for 'Range' header.";
|
||||
context.logger.error(message);
|
||||
const existingHeaders = getHeaderNames(res);
|
||||
for (let i = 0; i < existingHeaders.length; i++) {
|
||||
res.removeHeader(existingHeaders[i]);
|
||||
}
|
||||
setStatusCode(res, 416);
|
||||
setHeaderForResponse(res, "Content-Range", getValueContentRangeHeader("bytes", size));
|
||||
setHeaderForResponse(res, "Content-Type", "text/html; charset=utf-8");
|
||||
|
||||
/** @type {string | Buffer | import("fs").ReadStream} */
|
||||
let document = createHtmlDocument(416, `Error: ${message}`);
|
||||
let byteLength = Buffer.byteLength(document);
|
||||
setHeaderForResponse(res, "Content-Length", Buffer.byteLength(document));
|
||||
if (context.options.modifyResponseData) {
|
||||
({
|
||||
data: document,
|
||||
byteLength
|
||||
} = context.options.modifyResponseData(req, res, document, byteLength));
|
||||
}
|
||||
send(req, res, document, byteLength);
|
||||
return;
|
||||
} else if (parsedRanges === -2) {
|
||||
context.logger.error("A malformed 'Range' header was provided. A regular response will be sent for this request.");
|
||||
} else if (parsedRanges.length > 1) {
|
||||
context.logger.error("A 'Range' header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.");
|
||||
}
|
||||
if (parsedRanges !== -2 && parsedRanges.length === 1) {
|
||||
// Content-Range
|
||||
setStatusCode(res, 206);
|
||||
setHeaderForResponse(res, "Content-Range", getValueContentRangeHeader("bytes", size, /** @type {import("range-parser").Ranges} */parsedRanges[0]));
|
||||
[{
|
||||
start,
|
||||
end
|
||||
}] = parsedRanges;
|
||||
}
|
||||
}
|
||||
const isFsSupportsStream = typeof context.outputFileSystem.createReadStream === "function";
|
||||
let bufferOrStream;
|
||||
let byteLength;
|
||||
try {
|
||||
if (typeof start !== "undefined" && typeof end !== "undefined" && isFsSupportsStream) {
|
||||
bufferOrStream = /** @type {import("fs").createReadStream} */
|
||||
context.outputFileSystem.createReadStream(filename, {
|
||||
start,
|
||||
end
|
||||
});
|
||||
byteLength = end - start + 1;
|
||||
} else {
|
||||
bufferOrStream = /** @type {import("fs").readFileSync} */context.outputFileSystem.readFileSync(filename);
|
||||
({
|
||||
byteLength
|
||||
} = bufferOrStream);
|
||||
}
|
||||
} catch (_ignoreError) {
|
||||
await goNext();
|
||||
return;
|
||||
}
|
||||
if (context.options.modifyResponseData) {
|
||||
({
|
||||
data: bufferOrStream,
|
||||
byteLength
|
||||
} = context.options.modifyResponseData(req, res, bufferOrStream, byteLength));
|
||||
}
|
||||
send(req, res, bufferOrStream, byteLength);
|
||||
}
|
||||
};
|
||||
}
|
||||
module.exports = wrapper;
|
135
my-app/node_modules/webpack-dev-middleware/dist/options.json
generated
vendored
Executable file
135
my-app/node_modules/webpack-dev-middleware/dist/options.json
generated
vendored
Executable file
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mimeTypes": {
|
||||
"description": "Allows a user to register custom mime types or extension mappings.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#mimetypes",
|
||||
"type": "object"
|
||||
},
|
||||
"mimeTypeDefault": {
|
||||
"description": "Allows a user to register a default mime type when we can't determine the content type.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#mimetypedefault",
|
||||
"type": "string"
|
||||
},
|
||||
"writeToDisk": {
|
||||
"description": "Allows to write generated files on disk.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#writetodisk",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"methods": {
|
||||
"description": "Allows to pass the list of HTTP request methods accepted by the middleware.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#methods",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"key": {
|
||||
"description": "key of header.",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "value of header.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
],
|
||||
"description": "Allows to pass custom HTTP headers on each request",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#headers"
|
||||
},
|
||||
"publicPath": {
|
||||
"description": "The `publicPath` specifies the public URL address of the output files when referenced in a browser.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#publicpath",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": ["auto"]
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stats": {
|
||||
"description": "Stats options object or preset name.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#stats",
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": [
|
||||
"none",
|
||||
"summary",
|
||||
"errors-only",
|
||||
"errors-warnings",
|
||||
"minimal",
|
||||
"normal",
|
||||
"detailed",
|
||||
"verbose"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"serverSideRender": {
|
||||
"description": "Instructs the module to enable or disable the server-side rendering mode.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#serversiderender",
|
||||
"type": "boolean"
|
||||
},
|
||||
"outputFileSystem": {
|
||||
"description": "Set the default file system which will be used by webpack as primary destination of generated files.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#outputfilesystem",
|
||||
"type": "object"
|
||||
},
|
||||
"index": {
|
||||
"description": "Allows to serve an index of the directory.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#index",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"modifyResponseData": {
|
||||
"description": "Allows to set up a callback to change the response data.",
|
||||
"link": "https://github.com/webpack/webpack-dev-middleware#modifyresponsedata",
|
||||
"instanceof": "Function"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
144
my-app/node_modules/webpack-dev-middleware/dist/utils/compatibleAPI.js
generated
vendored
Executable file
144
my-app/node_modules/webpack-dev-middleware/dist/utils/compatibleAPI.js
generated
vendored
Executable file
|
@ -0,0 +1,144 @@
|
|||
"use strict";
|
||||
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExpectedRequest
|
||||
* @property {(name: string) => string | undefined} get
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExpectedResponse
|
||||
* @property {(name: string) => string | string[] | undefined} get
|
||||
* @property {(name: string, value: number | string | string[]) => void} set
|
||||
* @property {(status: number) => void} status
|
||||
* @property {(data: any) => void} send
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {ServerResponse} Response
|
||||
* @param {Response} res
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function getHeaderNames(res) {
|
||||
if (typeof res.getHeaderNames !== "function") {
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
return Object.keys(res._headers || {});
|
||||
}
|
||||
return res.getHeaderNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @param {Request} req
|
||||
* @param {string} name
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function getHeaderFromRequest(req, name) {
|
||||
// Express API
|
||||
if (typeof /** @type {Request & ExpectedRequest} */req.get === "function") {
|
||||
return (/** @type {Request & ExpectedRequest} */req.get(name)
|
||||
);
|
||||
}
|
||||
|
||||
// Node.js API
|
||||
// @ts-ignore
|
||||
return req.headers[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {ServerResponse} Response
|
||||
* @param {Response} res
|
||||
* @param {string} name
|
||||
* @returns {number | string | string[] | undefined}
|
||||
*/
|
||||
function getHeaderFromResponse(res, name) {
|
||||
// Express API
|
||||
if (typeof /** @type {Response & ExpectedResponse} */res.get === "function") {
|
||||
return (/** @type {Response & ExpectedResponse} */res.get(name)
|
||||
);
|
||||
}
|
||||
|
||||
// Node.js API
|
||||
return res.getHeader(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {ServerResponse} Response
|
||||
* @param {Response} res
|
||||
* @param {string} name
|
||||
* @param {number | string | string[]} value
|
||||
* @returns {void}
|
||||
*/
|
||||
function setHeaderForResponse(res, name, value) {
|
||||
// Express API
|
||||
if (typeof /** @type {Response & ExpectedResponse} */res.set === "function") {
|
||||
/** @type {Response & ExpectedResponse} */
|
||||
res.set(name, typeof value === "number" ? String(value) : value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Node.js API
|
||||
res.setHeader(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {ServerResponse} Response
|
||||
* @param {Response} res
|
||||
* @param {number} code
|
||||
*/
|
||||
function setStatusCode(res, code) {
|
||||
if (typeof /** @type {Response & ExpectedResponse} */res.status === "function") {
|
||||
/** @type {Response & ExpectedResponse} */
|
||||
res.status(code);
|
||||
return;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
res.statusCode = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {string | Buffer | import("fs").ReadStream} bufferOtStream
|
||||
* @param {number} byteLength
|
||||
*/
|
||||
function send(req, res, bufferOtStream, byteLength) {
|
||||
if (typeof /** @type {import("fs").ReadStream} */bufferOtStream.pipe === "function") {
|
||||
setHeaderForResponse(res, "Content-Length", byteLength);
|
||||
if (req.method === "HEAD") {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
/** @type {import("fs").ReadStream} */
|
||||
bufferOtStream.pipe(res);
|
||||
return;
|
||||
}
|
||||
if (typeof /** @type {Response & ExpectedResponse} */res.send === "function") {
|
||||
/** @type {Response & ExpectedResponse} */
|
||||
res.send(bufferOtStream);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only Node.js API used
|
||||
res.setHeader("Content-Length", byteLength);
|
||||
if (req.method === "HEAD") {
|
||||
res.end();
|
||||
} else {
|
||||
res.end(bufferOtStream);
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
getHeaderNames,
|
||||
getHeaderFromRequest,
|
||||
getHeaderFromResponse,
|
||||
setHeaderForResponse,
|
||||
setStatusCode,
|
||||
send
|
||||
};
|
118
my-app/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js
generated
vendored
Executable file
118
my-app/node_modules/webpack-dev-middleware/dist/utils/getFilenameFromUrl.js
generated
vendored
Executable file
|
@ -0,0 +1,118 @@
|
|||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const {
|
||||
parse
|
||||
} = require("url");
|
||||
const querystring = require("querystring");
|
||||
const getPaths = require("./getPaths");
|
||||
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
const cacheStore = new WeakMap();
|
||||
|
||||
/**
|
||||
* @param {Function} fn
|
||||
* @param {{ cache?: Map<any, any> }} [cache]
|
||||
* @returns {any}
|
||||
*/
|
||||
// @ts-ignore
|
||||
const mem = (fn, {
|
||||
cache = new Map()
|
||||
} = {}) => {
|
||||
/**
|
||||
* @param {any} arguments_
|
||||
* @return {any}
|
||||
*/
|
||||
const memoized = (...arguments_) => {
|
||||
const [key] = arguments_;
|
||||
const cacheItem = cache.get(key);
|
||||
if (cacheItem) {
|
||||
return cacheItem.data;
|
||||
}
|
||||
const result = fn.apply(void 0, arguments_);
|
||||
cache.set(key, {
|
||||
data: result
|
||||
});
|
||||
return result;
|
||||
};
|
||||
cacheStore.set(memoized, cache);
|
||||
return memoized;
|
||||
};
|
||||
const memoizedParse = mem(parse);
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
* @param {string} url
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function getFilenameFromUrl(context, url) {
|
||||
const {
|
||||
options
|
||||
} = context;
|
||||
const paths = getPaths(context);
|
||||
let foundFilename;
|
||||
let urlObject;
|
||||
try {
|
||||
// The `url` property of the `request` is contains only `pathname`, `search` and `hash`
|
||||
urlObject = memoizedParse(url, false, true);
|
||||
} catch (_ignoreError) {
|
||||
return;
|
||||
}
|
||||
for (const {
|
||||
publicPath,
|
||||
outputPath
|
||||
} of paths) {
|
||||
let filename;
|
||||
let publicPathObject;
|
||||
try {
|
||||
publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
if (urlObject.pathname && urlObject.pathname.startsWith(publicPathObject.pathname)) {
|
||||
filename = outputPath;
|
||||
|
||||
// Strip the `pathname` property from the `publicPath` option from the start of requested url
|
||||
// `/complex/foo.js` => `foo.js`
|
||||
const pathname = urlObject.pathname.slice(publicPathObject.pathname.length);
|
||||
if (pathname) {
|
||||
filename = path.join(outputPath, querystring.unescape(pathname));
|
||||
}
|
||||
let fsStats;
|
||||
try {
|
||||
fsStats = /** @type {import("fs").statSync} */
|
||||
context.outputFileSystem.statSync(filename);
|
||||
} catch (_ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
if (fsStats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
} else if (fsStats.isDirectory() && (typeof options.index === "undefined" || options.index)) {
|
||||
const indexValue = typeof options.index === "undefined" || typeof options.index === "boolean" ? "index.html" : options.index;
|
||||
filename = path.join(filename, indexValue);
|
||||
try {
|
||||
fsStats = /** @type {import("fs").statSync} */
|
||||
context.outputFileSystem.statSync(filename);
|
||||
} catch (__ignoreError) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
if (fsStats.isFile()) {
|
||||
foundFilename = filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
return foundFilename;
|
||||
}
|
||||
module.exports = getFilenameFromUrl;
|
36
my-app/node_modules/webpack-dev-middleware/dist/utils/getPaths.js
generated
vendored
Executable file
36
my-app/node_modules/webpack-dev-middleware/dist/utils/getPaths.js
generated
vendored
Executable file
|
@ -0,0 +1,36 @@
|
|||
"use strict";
|
||||
|
||||
/** @typedef {import("webpack").Compiler} Compiler */
|
||||
/** @typedef {import("webpack").Stats} Stats */
|
||||
/** @typedef {import("webpack").MultiStats} MultiStats */
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
*/
|
||||
function getPaths(context) {
|
||||
const {
|
||||
stats,
|
||||
options
|
||||
} = context;
|
||||
/** @type {Stats[]} */
|
||||
const childStats = /** @type {MultiStats} */
|
||||
stats.stats ? /** @type {MultiStats} */stats.stats : [/** @type {Stats} */stats];
|
||||
const publicPaths = [];
|
||||
for (const {
|
||||
compilation
|
||||
} of childStats) {
|
||||
// The `output.path` is always present and always absolute
|
||||
const outputPath = compilation.getPath(compilation.outputOptions.path || "");
|
||||
const publicPath = options.publicPath ? compilation.getPath(options.publicPath) : compilation.outputOptions.publicPath ? compilation.getPath(compilation.outputOptions.publicPath) : "";
|
||||
publicPaths.push({
|
||||
outputPath,
|
||||
publicPath
|
||||
});
|
||||
}
|
||||
return publicPaths;
|
||||
}
|
||||
module.exports = getPaths;
|
23
my-app/node_modules/webpack-dev-middleware/dist/utils/ready.js
generated
vendored
Executable file
23
my-app/node_modules/webpack-dev-middleware/dist/utils/ready.js
generated
vendored
Executable file
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
* @param {(...args: any[]) => any} callback
|
||||
* @param {Request} [req]
|
||||
* @returns {void}
|
||||
*/
|
||||
function ready(context, callback, req) {
|
||||
if (context.state) {
|
||||
callback(context.stats);
|
||||
return;
|
||||
}
|
||||
const name = req && req.url || callback.name;
|
||||
context.logger.info(`wait until bundle finished${name ? `: ${name}` : ""}`);
|
||||
context.callbacks.push(callback);
|
||||
}
|
||||
module.exports = ready;
|
154
my-app/node_modules/webpack-dev-middleware/dist/utils/setupHooks.js
generated
vendored
Executable file
154
my-app/node_modules/webpack-dev-middleware/dist/utils/setupHooks.js
generated
vendored
Executable file
|
@ -0,0 +1,154 @@
|
|||
"use strict";
|
||||
|
||||
/** @typedef {import("webpack").Configuration} Configuration */
|
||||
/** @typedef {import("webpack").Compiler} Compiler */
|
||||
/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
|
||||
/** @typedef {import("webpack").Stats} Stats */
|
||||
/** @typedef {import("webpack").MultiStats} MultiStats */
|
||||
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
/** @typedef {Configuration["stats"]} StatsOptions */
|
||||
/** @typedef {{ children: Configuration["stats"][] }} MultiStatsOptions */
|
||||
/** @typedef {Exclude<Configuration["stats"], boolean | string | undefined>} NormalizedStatsOptions */
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
*/
|
||||
function setupHooks(context) {
|
||||
function invalid() {
|
||||
if (context.state) {
|
||||
context.logger.log("Compilation starting...");
|
||||
}
|
||||
|
||||
// We are now in invalid state
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.state = false;
|
||||
// eslint-disable-next-line no-param-reassign, no-undefined
|
||||
context.stats = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Configuration["stats"]} statsOptions
|
||||
* @returns {NormalizedStatsOptions}
|
||||
*/
|
||||
function normalizeStatsOptions(statsOptions) {
|
||||
if (typeof statsOptions === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {
|
||||
preset: "normal"
|
||||
};
|
||||
} else if (typeof statsOptions === "boolean") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = statsOptions ? {
|
||||
preset: "normal"
|
||||
} : {
|
||||
preset: "none"
|
||||
};
|
||||
} else if (typeof statsOptions === "string") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
statsOptions = {
|
||||
preset: statsOptions
|
||||
};
|
||||
}
|
||||
return statsOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Stats | MultiStats} stats
|
||||
*/
|
||||
function done(stats) {
|
||||
// We are now on valid state
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.state = true;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.stats = stats;
|
||||
|
||||
// Do the stuff in nextTick, because bundle may be invalidated if a change happened while compiling
|
||||
process.nextTick(() => {
|
||||
const {
|
||||
compiler,
|
||||
logger,
|
||||
options,
|
||||
state,
|
||||
callbacks
|
||||
} = context;
|
||||
|
||||
// Check if still in valid state
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
logger.log("Compilation finished");
|
||||
const isMultiCompilerMode = Boolean( /** @type {MultiCompiler} */
|
||||
compiler.compilers);
|
||||
|
||||
/**
|
||||
* @type {StatsOptions | MultiStatsOptions | NormalizedStatsOptions}
|
||||
*/
|
||||
let statsOptions;
|
||||
if (typeof options.stats !== "undefined") {
|
||||
statsOptions = isMultiCompilerMode ? {
|
||||
children: /** @type {MultiCompiler} */
|
||||
compiler.compilers.map(() => options.stats)
|
||||
} : options.stats;
|
||||
} else {
|
||||
statsOptions = isMultiCompilerMode ? {
|
||||
children: /** @type {MultiCompiler} */
|
||||
compiler.compilers.map(child => child.options.stats)
|
||||
} : /** @type {Compiler} */compiler.options.stats;
|
||||
}
|
||||
if (isMultiCompilerMode) {
|
||||
/** @type {MultiStatsOptions} */
|
||||
statsOptions.children = /** @type {MultiStatsOptions} */
|
||||
statsOptions.children.map(
|
||||
/**
|
||||
* @param {StatsOptions} childStatsOptions
|
||||
* @return {NormalizedStatsOptions}
|
||||
*/
|
||||
childStatsOptions => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
childStatsOptions = normalizeStatsOptions(childStatsOptions);
|
||||
if (typeof childStatsOptions.colors === "undefined") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
childStatsOptions.colors =
|
||||
// eslint-disable-next-line global-require
|
||||
require("colorette").isColorSupported;
|
||||
}
|
||||
return childStatsOptions;
|
||||
});
|
||||
} else {
|
||||
/** @type {NormalizedStatsOptions} */
|
||||
statsOptions = normalizeStatsOptions( /** @type {StatsOptions} */statsOptions);
|
||||
if (typeof statsOptions.colors === "undefined") {
|
||||
// eslint-disable-next-line global-require
|
||||
statsOptions.colors = require("colorette").isColorSupported;
|
||||
}
|
||||
}
|
||||
const printedStats = stats.toString(statsOptions);
|
||||
|
||||
// Avoid extra empty line when `stats: 'none'`
|
||||
if (printedStats) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(printedStats);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.callbacks = [];
|
||||
|
||||
// Execute callback that are delayed
|
||||
callbacks.forEach(
|
||||
/**
|
||||
* @param {(...args: any[]) => Stats | MultiStats} callback
|
||||
*/
|
||||
callback => {
|
||||
callback(stats);
|
||||
});
|
||||
});
|
||||
}
|
||||
context.compiler.hooks.watchRun.tap("webpack-dev-middleware", invalid);
|
||||
context.compiler.hooks.invalid.tap("webpack-dev-middleware", invalid);
|
||||
context.compiler.hooks.done.tap("webpack-dev-middleware", done);
|
||||
}
|
||||
module.exports = setupHooks;
|
53
my-app/node_modules/webpack-dev-middleware/dist/utils/setupOutputFileSystem.js
generated
vendored
Executable file
53
my-app/node_modules/webpack-dev-middleware/dist/utils/setupOutputFileSystem.js
generated
vendored
Executable file
|
@ -0,0 +1,53 @@
|
|||
"use strict";
|
||||
|
||||
const memfs = require("memfs");
|
||||
|
||||
/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
*/
|
||||
function setupOutputFileSystem(context) {
|
||||
let outputFileSystem;
|
||||
if (context.options.outputFileSystem) {
|
||||
const {
|
||||
outputFileSystem: outputFileSystemFromOptions
|
||||
} = context.options;
|
||||
outputFileSystem = outputFileSystemFromOptions;
|
||||
}
|
||||
// Don't use `memfs` when developer wants to write everything to a disk, because it doesn't make sense.
|
||||
else if (context.options.writeToDisk !== true) {
|
||||
outputFileSystem = memfs.createFsFromVolume(new memfs.Volume());
|
||||
} else {
|
||||
const isMultiCompiler = /** @type {MultiCompiler} */
|
||||
context.compiler.compilers;
|
||||
if (isMultiCompiler) {
|
||||
// Prefer compiler with `devServer` option or fallback on the first
|
||||
// TODO we need to support webpack-dev-server as a plugin or revisit it
|
||||
const compiler = /** @type {MultiCompiler} */
|
||||
context.compiler.compilers.filter(item => Object.prototype.hasOwnProperty.call(item.options, "devServer"));
|
||||
({
|
||||
outputFileSystem
|
||||
} = compiler[0] || /** @type {MultiCompiler} */
|
||||
context.compiler.compilers[0]);
|
||||
} else {
|
||||
({
|
||||
outputFileSystem
|
||||
} = context.compiler);
|
||||
}
|
||||
}
|
||||
const compilers = /** @type {MultiCompiler} */
|
||||
context.compiler.compilers || [context.compiler];
|
||||
for (const compiler of compilers) {
|
||||
compiler.outputFileSystem = outputFileSystem;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context.outputFileSystem = outputFileSystem;
|
||||
}
|
||||
module.exports = setupOutputFileSystem;
|
66
my-app/node_modules/webpack-dev-middleware/dist/utils/setupWriteToDisk.js
generated
vendored
Executable file
66
my-app/node_modules/webpack-dev-middleware/dist/utils/setupWriteToDisk.js
generated
vendored
Executable file
|
@ -0,0 +1,66 @@
|
|||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
/** @typedef {import("webpack").Compiler} Compiler */
|
||||
/** @typedef {import("webpack").MultiCompiler} MultiCompiler */
|
||||
/** @typedef {import("webpack").Compilation} Compilation */
|
||||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
|
||||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */
|
||||
|
||||
/**
|
||||
* @template {IncomingMessage} Request
|
||||
* @template {ServerResponse} Response
|
||||
* @param {import("../index.js").Context<Request, Response>} context
|
||||
*/
|
||||
function setupWriteToDisk(context) {
|
||||
/**
|
||||
* @type {Compiler[]}
|
||||
*/
|
||||
const compilers = /** @type {MultiCompiler} */
|
||||
context.compiler.compilers || [context.compiler];
|
||||
for (const compiler of compilers) {
|
||||
compiler.hooks.emit.tap("DevMiddleware", () => {
|
||||
// @ts-ignore
|
||||
if (compiler.hasWebpackDevMiddlewareAssetEmittedCallback) {
|
||||
return;
|
||||
}
|
||||
compiler.hooks.assetEmitted.tapAsync("DevMiddleware", (file, info, callback) => {
|
||||
const {
|
||||
targetPath,
|
||||
content
|
||||
} = info;
|
||||
const {
|
||||
writeToDisk: filter
|
||||
} = context.options;
|
||||
const allowWrite = filter && typeof filter === "function" ? filter(targetPath) : true;
|
||||
if (!allowWrite) {
|
||||
return callback();
|
||||
}
|
||||
const dir = path.dirname(targetPath);
|
||||
const name = compiler.options.name ? `Child "${compiler.options.name}": ` : "";
|
||||
return fs.mkdir(dir, {
|
||||
recursive: true
|
||||
}, mkdirError => {
|
||||
if (mkdirError) {
|
||||
context.logger.error(`${name}Unable to write "${dir}" directory to disk:\n${mkdirError}`);
|
||||
return callback(mkdirError);
|
||||
}
|
||||
return fs.writeFile(targetPath, content, writeFileError => {
|
||||
if (writeFileError) {
|
||||
context.logger.error(`${name}Unable to write "${targetPath}" asset to disk:\n${writeFileError}`);
|
||||
return callback(writeFileError);
|
||||
}
|
||||
context.logger.log(`${name}Asset written to disk: "${targetPath}"`);
|
||||
return callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
compiler.hasWebpackDevMiddlewareAssetEmittedCallback = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = setupWriteToDisk;
|
Loading…
Add table
Add a link
Reference in a new issue