UNPKG

webpack-mock-server

Version:

Mocks api requests for webpack-dev-server with hot-replacement

182 lines (181 loc) 8.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = compiler; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const typescript_1 = __importDefault(require("typescript")); const compilerOutRootFiles_1 = __importDefault(require("./compilerOutRootFiles")); const log_1 = __importDefault(require("./log")); const versionContainer_1 = __importStar(require("./versionContainer")); const formatHost = { getCanonicalFileName: (path) => path, getCurrentDirectory: typescript_1.default.sys.getCurrentDirectory, getNewLine: () => typescript_1.default.sys.newLine, }; function reportDiagnostic(diagnostic) { var _a; let linePointer = ""; if (diagnostic.file) { const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start || 0); linePointer = `in ${(_a = diagnostic.file) === null || _a === void 0 ? void 0 : _a.fileName} (${line + 1},${character + 1})`; } log_1.default.error(`TS${diagnostic.code}: ${linePointer}\n${typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, formatHost.getNewLine())}`); } function clearNodeCache(rootPath) { Object.keys(require.cache).forEach((key) => { var _a; if ((_a = require.cache[key]) === null || _a === void 0 ? void 0 : _a.filename.startsWith(rootPath)) { log_1.default.debug("delete node-cache for", key); delete require.cache[key]; } }); } function compiler(entry, tsConfigFileName, extendCompilerOptions, onChanged) { const tsVer = Number.parseFloat(typescript_1.default.versionMajorMinor); if (tsVer < 2.7) { throw new Error(`WebpackMockServer. Typescript version >=2.7 is expected. Current is ${typescript_1.default.versionMajorMinor}`); } log_1.default.debug(`typescript version: ${typescript_1.default.version}`); const entries = entry && (Array.isArray(entry) ? entry : [entry]); entries && entries.forEach((v) => { if (typeof v !== "string") { throw new Error(`WebpackMockServer. Option [entry]. Only 'string' is expected: ${v}`); } if (v.includes("*")) { throw new Error(`WebpackMockServer. Option [entry]. Wildcard is not supported. Set 'Null' to [entry] and use tsConfig.json with 'files' and 'include' options instead. More details here: https://github.com/Yegorich555/webpack-mock-server#options`); } }); let isOutputChanged = true; const outMockFiles = new compilerOutRootFiles_1.default(); const emptyWatcher = { close: () => { }, }; const sysConfig = Object.assign({}, typescript_1.default.sys); sysConfig.watchFile = function watchFile(path) { if (path.includes("node_modules")) { return emptyWatcher; } return typescript_1.default.sys.watchFile(...arguments); }; sysConfig.watchDirectory = function watchDir(path) { if (path.includes("node_modules")) { return emptyWatcher; } return typescript_1.default.sys.watchDirectory(...arguments); }; function resolvePathAlias(filePath, path) { var _a; const isMatchAlias = definedTSOptions.pathsArr.some((v) => v[0] === filePath[0]); if (isMatchAlias) { const m = (_a = typescript_1.default.resolveModuleName(filePath, path, definedTSOptions, host).resolvedModule) === null || _a === void 0 ? void 0 : _a.resolvedFileName; return m || filePath; } return filePath; } sysConfig.writeFile = function writeFile(path, data) { log_1.default.debug("write", path); isOutputChanged = true; if (data) { arguments[1] = data.replace(/require\(["']([^./\\][^\n\r]+)["']\)/g, (_str, mPath) => `require(require.resolve("${resolvePathAlias(mPath, path)}", {paths:[process.cwd(), "${process.env.NODE_PATH || ''}"]} ))`); } return typescript_1.default.sys.writeFile(...arguments); }; sysConfig.readFile = function readFile(path) { log_1.default.debug("read", path); const data = typescript_1.default.sys.readFile(...arguments); if (!data && path === tsConfigFileName) { log_1.default.debug(`file ${tsConfigFileName} is not found. Compilation with default settings...`); return JSON.stringify({}); } if (!data || path.includes("node_modules")) { return data; } const absolutePath = path_1.default.resolve(path); return data .replace(/(?<![/).])__dirname/g, `String.raw\`${path_1.default.dirname(absolutePath)}\``) .replace(/(?<![/).])__filename/g, `String.raw\`${absolutePath}\``); }; const host = typescript_1.default.createWatchCompilerHost(tsConfigFileName, extendCompilerOptions, sysConfig, typescript_1.default.createEmitAndSemanticDiagnosticsBuilderProgram, reportDiagnostic, (diagnostic) => { if (isOutputChanged && onChanged && diagnostic.code === 6194) { clearNodeCache(extendCompilerOptions.outDir); onChanged(outMockFiles.files.filter((f) => !f.rootName.endsWith(".d.ts"))); isOutputChanged = false; } else { log_1.default.debug(typescript_1.default.formatDiagnostic(diagnostic, formatHost)); } }); let definedTSOptions; const origCreateProgram = host.createProgram; host.createProgram = function hookCreateProgram(tsRootNames, allOptions) { const definedRootNames = entries && entries.length ? entries : tsRootNames; arguments[0] = definedRootNames; if (allOptions) { definedTSOptions = JSON.parse(JSON.stringify(allOptions)); definedTSOptions.baseUrl = definedTSOptions.outDir; definedTSOptions.pathsArr = (definedTSOptions.paths && Object.keys(definedTSOptions.paths)) || []; isOutputChanged = outMockFiles.update(definedRootNames, allOptions.rootDir, allOptions.outDir); log_1.default.debug("defined root names", "", definedRootNames); log_1.default.debug("TS options", "", allOptions); } return origCreateProgram(...arguments); }; const program = typescript_1.default.createWatchProgram(host); function clearTmpOutput() { log_1.default.debug("clearing tmp folder ", extendCompilerOptions.outDir); try { fs_1.default.rmdirSync(extendCompilerOptions.outDir, { recursive: true, }); } catch (ex) { const nodeJsRequired = new versionContainer_1.default("12.10.0"); if (versionContainer_1.nodeJsVer > nodeJsRequired) log_1.default.error("error in clearing tmp folder", ex); } } let closed = false; function close() { if (closed) { return; } program && program.close(); clearTmpOutput(); closed = true; } const signals = ["SIGINT", "SIGTERM"]; signals.forEach((s) => { process.on(s, () => { close(); process.exit(); }); }); }