UNPKG

webpack

Version:

Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.

105 lines (99 loc) 3.05 kB
/* 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 }; } }); }); };