Current File : /home/tradevaly/www/node_modules/webpack/lib/hmr/lazyCompilationBackend.js |
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const http = require("http");
/** @typedef {import("../Compiler")} Compiler */
/**
* @param {Compiler} compiler compiler
* @param {string} client client reference
* @param {function(Error?, any?): void} callback callback
* @returns {void}
*/
module.exports = (compiler, client, callback) => {
const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
const activeModules = new Map();
const prefix = "/lazy-compilation-using-";
const requestListener = (req, res) => {
const keys = req.url.slice(prefix.length).split("@");
req.socket.on("close", () => {
setTimeout(() => {
for (const key of keys) {
const oldValue = activeModules.get(key) || 0;
activeModules.set(key, oldValue - 1);
if (oldValue === 1) {
logger.log(
`${key} is no longer in use. Next compilation will skip this module.`
);
}
}
}, 120000);
});
req.socket.setNoDelay(true);
res.writeHead(200, {
"content-type": "text/event-stream",
"Access-Control-Allow-Origin": "*"
});
res.write("\n");
let moduleActivated = false;
for (const key of keys) {
const oldValue = activeModules.get(key) || 0;
activeModules.set(key, oldValue + 1);
if (oldValue === 0) {
logger.log(`${key} is now in use and will be compiled.`);
moduleActivated = true;
}
}
if (moduleActivated && compiler.watching) compiler.watching.invalidate();
};
const server = http.createServer(requestListener);
let isClosing = false;
/** @type {Set<import("net").Socket>} */
const sockets = new Set();
server.on("connection", socket => {
sockets.add(socket);
socket.on("close", () => {
sockets.delete(socket);
});
if (isClosing) socket.destroy();
});
server.listen(err => {
if (err) return callback(err);
const addr = server.address();
if (typeof addr === "string") throw new Error("addr must not be a string");
const urlBase =
addr.address === "::" || addr.address === "0.0.0.0"
? `http://localhost:${addr.port}`
: addr.family === "IPv6"
? `http://[${addr.address}]:${addr.port}`
: `http://${addr.address}:${addr.port}`;
logger.log(
`Server-Sent-Events server for lazy compilation open at ${urlBase}.`
);
callback(null, {
dispose(callback) {
isClosing = true;
// Removing the listener is a workaround for a memory leak in node.js
server.off("request", requestListener);
server.close(err => {
callback(err);
});
for (const socket of sockets) {
socket.destroy(new Error("Server is disposing"));
}
},
module(originalModule) {
const key = `${encodeURIComponent(
originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_")
).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
const active = activeModules.get(key) > 0;
return {
client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
data: key,
active
};
}
});
});
};