ngc-webpack
Version:
A wrapper for the @ngtools/webpack with hooks into the compilation process
115 lines • 6.02 kB
JavaScript
;
// Taken from
// https://github.com/angular/angular-cli/blob/master/packages/%40ngtools/webpack/src/resource_loader.ts
Object.defineProperty(exports, "__esModule", { value: true });
var vm = require("vm");
var path = require("path");
var NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
var LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
var WebpackResourceLoader = (function () {
function WebpackResourceLoader() {
this._uniqueId = 0;
this._resourceDependencies = new Map();
}
WebpackResourceLoader.prototype.update = function (parentCompilation) {
this._parentCompilation = parentCompilation;
this._context = parentCompilation.context;
this._uniqueId = 0;
};
WebpackResourceLoader.prototype.getResourceDependencies = function (filePath) {
return this._resourceDependencies.get(filePath) || [];
};
WebpackResourceLoader.prototype._compile = function (filePath) {
var _this = this;
if (!this._parentCompilation) {
throw new Error('WebpackResourceLoader cannot be used without parentCompilation');
}
var compilerName = "compiler(" + this._uniqueId++ + ")";
var outputOptions = { filename: filePath };
var relativePath = path.relative(this._context || '', filePath);
var childCompiler = this._parentCompilation.createChildCompiler(relativePath, outputOptions);
childCompiler.context = this._context;
childCompiler.apply(new NodeTemplatePlugin(outputOptions), new NodeTargetPlugin(), new SingleEntryPlugin(this._context, filePath), new LoaderTargetPlugin('node'));
// Store the result of the parent compilation before we start the child compilation
var assetsBeforeCompilation = Object.assign({}, this._parentCompilation.assets[outputOptions.filename]);
// Fix for "Uncaught TypeError: __webpack_require__(...) is not a function"
// Hot module replacement requires that every child compiler has its own
// cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179
childCompiler.plugin('compilation', function (compilation) {
if (compilation.cache) {
if (!compilation.cache[compilerName]) {
compilation.cache[compilerName] = {};
}
compilation.cache = compilation.cache[compilerName];
}
});
// Compile and return a promise
return new Promise(function (resolve, reject) {
childCompiler.runAsChild(function (err, entries, childCompilation) {
// Resolve / reject the promise
if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
var errorDetails = childCompilation.errors.map(function (error) {
return error.message + (error.error ? ':\n' + error.error : '');
}).join('\n');
reject(new Error('Child compilation failed:\n' + errorDetails));
}
else if (err) {
reject(err);
}
else {
// Replace [hash] placeholders in filename
var outputName = _this._parentCompilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
hash: childCompilation.hash,
chunk: entries[0]
});
// Restore the parent compilation to the state like it was before the child compilation.
Object.keys(childCompilation.assets).forEach(function (fileName) {
// If it wasn't there and it's a source file (absolute path) - delete it.
if (assetsBeforeCompilation[fileName] === undefined && path.isAbsolute(fileName)) {
delete _this._parentCompilation.assets[fileName];
}
else {
// Otherwise, add it to the parent compilation.
_this._parentCompilation.assets[fileName] = childCompilation.assets[fileName];
}
});
// Save the dependencies for this resource.
_this._resourceDependencies.set(outputName, childCompilation.fileDependencies);
resolve({
// Output name.
outputName: outputName,
// Compiled code.
source: childCompilation.assets[outputName].source()
});
}
});
});
};
WebpackResourceLoader.prototype._evaluate = function (output) {
try {
var outputName = output.outputName;
var vmContext = vm.createContext(Object.assign({ require: require }, global));
var vmScript = new vm.Script(output.source, { filename: outputName });
// Evaluate code and cast to string
var evaluatedSource = void 0;
evaluatedSource = vmScript.runInContext(vmContext);
if (typeof evaluatedSource == 'string') {
return Promise.resolve(evaluatedSource);
}
return Promise.reject('The loader "' + outputName + '" didn\'t return a string.');
}
catch (e) {
return Promise.reject(e);
}
};
WebpackResourceLoader.prototype.get = function (filePath) {
var _this = this;
return this._compile(filePath)
.then(function (result) { return _this._evaluate(result); });
};
return WebpackResourceLoader;
}());
exports.WebpackResourceLoader = WebpackResourceLoader;
//# sourceMappingURL=_resource-loader.js.map