UNPKG

@injectable/webpack-service

Version:
226 lines (225 loc) 10.3 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var core_1 = require("@injectable/core"); var log_service_1 = require("@injectable/log-service"); var webpack_1 = __importDefault(require("webpack")); var memory_fs_1 = __importDefault(require("memory-fs")); var unionfs_1 = require("unionfs"); var fs_1 = __importDefault(require("fs")); var path_1 = require("path"); var WebpackService = /** @class */ (function (_super) { __extends(WebpackService, _super); function WebpackService() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.resourceStore = new core_1.ResourceStore(); _this.counter = 0; return _this; } WebpackService.prototype.prepare = function () { this.start(); }; /** * registers an id for a compilation */ WebpackService.prototype.registerCompilationId = function () { var id = this.counter; ++this.counter; return id; }; /** * Sets a compilation to be compiled and then hosted. * @param injectableName creator injectable * @param compilationId id of the compilation * @param files files to compile * @param configuration webpack configuration * @param baseRoute base route to host the files on * @param encodings all possible encodings * @param onRequest callback to verify the file request */ WebpackService.prototype.setCompilation = function (injectableName, compilationId, files, configuration, baseRoute, encodings, onRequest) { var _this = this; this.compileFiles(injectableName, compilationId, files, configuration) .then(function (files) { _this.dependencies.LogService.log(_this.typeNames[0], log_service_1.LogLevel.INFO, "Compiled files for \"" + baseRoute + "\"."); var compilationFileIds = _this.resourceStore.getResource(injectableName, "comilationFileIds"); if (compilationFileIds != null) { var fileIds = compilationFileIds.get(compilationId); if (fileIds) { fileIds.forEach(function (fileId) { return _this.dependencies.FileHostingService.deleteFile(_this.typeNames[0], fileId); }); } } else { compilationFileIds = new Map(); _this.resourceStore.setResource(injectableName, "comilationFileIds", compilationFileIds); } compilationFileIds.set(compilationId, Object.entries(files) .map(function (_a) { var fileName = _a[0], buffer = _a[1]; var id = _this.dependencies.FileHostingService.registerFileId(); _this.dependencies.FileHostingService.setFile(_this.typeNames[0], id, "" + baseRoute + fileName, buffer, encodings, function (req, res) { res.set("Content-Type", "application/x-javascript"); if (onRequest != null) { return onRequest(req, res); } else { return Promise.resolve(true); } }); return id; })); }) .catch(function (error) { return _this.dependencies.LogService.log(_this.typeNames[0], log_service_1.LogLevel.ERROR, error.toString()); }); }; /** * deletes a compilation and all hosted files assoicated with it * @param injectableName creator injectable * @param compilationId id of the compilation */ WebpackService.prototype.deleteCompilation = function (injectableName, compilationId) { var _this = this; var compilationFileIds = this.resourceStore.getResource(injectableName, "comilationFileIds"); if (compilationFileIds != null) { var fileIds = compilationFileIds.get(compilationId); if (fileIds != null) { fileIds.forEach(function (fileId) { return _this.dependencies.FileHostingService.deleteFile(_this.typeNames[0], fileId); }); compilationFileIds.delete(compilationId); } } var compileRequests = this.resourceStore.getResource(injectableName, "compilationRequests"); if (compileRequests != null) { compileRequests.delete(compilationId); } }; WebpackService.prototype.onClose = function () { }; WebpackService.prototype.removeResources = function (injectableName) { var _this = this; var compilationFileIds = this.resourceStore.getResource(injectableName, "comilationFileIds"); if (compilationFileIds != null) { compilationFileIds.forEach(function (fileIds) { return fileIds.forEach(function (fileId) { return _this.dependencies.FileHostingService.deleteFile(_this.typeNames[0], fileId); }); }); } this.resourceStore.removeResources(injectableName); }; WebpackService.prototype.compileFiles = function (injectableName, compilationId, files, configuration) { var _this = this; return new Promise(function (resolve, reject) { var compileRequestMap = _this.resourceStore.getResource(injectableName, "compilationRequests"); if (compileRequestMap == null) { compileRequestMap = new Map([]); _this.resourceStore.setResource(injectableName, "compilationRequests", compileRequestMap); } var compileRequests = compileRequestMap.get(compilationId); var request = { resolve: resolve, reject: reject, files: files, configuration: configuration }; if (compileRequests == null) { compileRequests = [request]; compileRequestMap.set(compilationId, compileRequests); } else { //the queue is just 2 long, and the last entry gets overwritten because it got updated compileRequests[Math.min(compileRequests.length, 1)] = request; } if (compileRequests.length > 0) { _this.compileQueue(compileRequests); } }); }; /** * * queue.length must be at least 1 * @param hash * @param compileRequests */ WebpackService.prototype.compileQueue = function (compileRequests) { var _this = this; var request = compileRequests.shift(); this.compile(request.files, request.configuration) .then(function (result) { request.resolve(result); if (compileRequests.length > 0) { _this.compileQueue(compileRequests); } }) .catch(request.reject); }; WebpackService.prototype.compile = function (files, configuration) { //TODO all dynamic imports need to get recompiled even if just one changes var inputMemFs = new memory_fs_1.default(); var outputMemFs = new memory_fs_1.default(); var unionFs = new unionfs_1.Union(); unionFs.use(fs_1.default).use(inputMemFs); Object.entries(files).forEach(function (_a) { var filename = _a[0], code = _a[1]; return inputMemFs.writeFileSync("/" + filename, code); }); var webpackOutput = configuration.output || {}; var webpackResolve = configuration.resolve || {}; var webpackModules = webpackResolve.modules || []; var nodeModulesPath = path_1.resolve(process.cwd(), "node_modules"); webpackModules.push(nodeModulesPath); webpackOutput.publicPath = "/"; webpackOutput.path = "/"; webpackResolve.modules = webpackModules; configuration.output = webpackOutput; configuration.resolve = webpackResolve; return new Promise(function (resolve, reject) { var compiler = webpack_1.default(configuration); compiler.inputFileSystem = unionFs; compiler.outputFileSystem = outputMemFs; compiler.run(function (_error, stats) { if (stats.hasErrors()) { reject(stats.toString("errors-only")); } else { var files_1 = Object.entries(outputMemFs.data) .reduce(function (prev, _a) { var filename = _a[0], code = _a[1]; prev[filename] = code; return prev; }, {}); resolve(files_1); } }); }); }; return WebpackService; }(core_1.Injectable)); exports.WebpackService = WebpackService; var WebpackServiceContainer = /** @class */ (function (_super) { __extends(WebpackServiceContainer, _super); function WebpackServiceContainer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.typeNames = ["WebpackService"]; _this.injectableClass = WebpackService; _this.dependencyTypeNames = ["FileHostingService", "LogService"]; return _this; } return WebpackServiceContainer; }(core_1.InjectableContainer)); exports.default = WebpackServiceContainer;