@injectable/webpack-service
Version:
service for compiling strings to js
226 lines (225 loc) • 10.3 kB
JavaScript
;
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;