electron-compile
Version:
Electron supporting package to compile JS and CSS in Electron applications
789 lines (623 loc) • 90.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _mimeTypes = require('@paulcbetts/mime-types');
var _mimeTypes2 = _interopRequireDefault(_mimeTypes);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _zlib = require('zlib');
var _zlib2 = _interopRequireDefault(_zlib);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _promise = require('./promise');
var _forAllFiles = require('./for-all-files');
var _compileCache = require('./compile-cache');
var _compileCache2 = _interopRequireDefault(_compileCache);
var _fileChangeCache = require('./file-change-cache');
var _fileChangeCache2 = _interopRequireDefault(_fileChangeCache);
var _readOnlyCompiler = require('./read-only-compiler');
var _readOnlyCompiler2 = _interopRequireDefault(_readOnlyCompiler);
var _browserSignal = require('./browser-signal');
require('rxjs/add/operator/map');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const d = require('debug')('electron-compile:compiler-host');
require('./rig-mime-types').init();
// This isn't even my
const finalForms = {
'text/javascript': true,
'application/javascript': true,
'text/html': true,
'text/css': true,
'image/svg+xml': true,
'application/json': true
};
/**
* This class is the top-level class that encapsulates all of the logic of
* compiling and caching application code. If you're looking for a "Main class",
* this is it.
*
* This class can be created directly but it is usually created via the methods
* in config-parser, which will among other things, set up the compiler options
* given a project root.
*
* CompilerHost is also the top-level class that knows how to serialize all of the
* information necessary to recreate itself, either as a development host (i.e.
* will allow cache misses and actual compilation), or as a read-only version of
* itself for production.
*/
class CompilerHost {
/**
* Creates an instance of CompilerHost. You probably want to use the methods
* in config-parser for development, or {@link createReadonlyFromConfiguration}
* for production instead.
*
* @param {string} rootCacheDir The root directory to use for the cache
*
* @param {Object} compilers an Object whose keys are input MIME types and
* whose values are instances of CompilerBase. Create
* this via the {@link createCompilers} method in
* config-parser.
*
* @param {FileChangedCache} fileChangeCache A file-change cache that is
* optionally pre-loaded.
*
* @param {boolean} readOnlyMode If True, cache misses will fail and
* compilation will not be attempted.
*
* @param {CompilerBase} fallbackCompiler (optional) When a file is compiled
* which doesn't have a matching compiler,
* this compiler will be used instead. If
* null, will fail compilation. A good
* alternate fallback is the compiler for
* 'text/plain', which is guaranteed to be
* present.
*
* @param {string} sourceMapPath (optional) The directory to store sourcemap separately
* if compiler option enabled to emit.
* Default to cachePath if not specified.
*/
constructor(rootCacheDir, compilers, fileChangeCache, readOnlyMode) {
let fallbackCompiler = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
let sourceMapPath = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
let mimeTypesToRegister = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
let compilersByMimeType = Object.assign({}, compilers);
Object.assign(this, { rootCacheDir, compilersByMimeType, fileChangeCache, readOnlyMode, fallbackCompiler });
this.appRoot = this.fileChangeCache.appRoot;
this.cachesForCompilers = Object.keys(compilersByMimeType).reduce((acc, x) => {
let compiler = compilersByMimeType[x];
if (acc.has(compiler)) return acc;
acc.set(compiler, _compileCache2.default.createFromCompiler(rootCacheDir, compiler, fileChangeCache, readOnlyMode, sourceMapPath));
return acc;
}, new Map());
this.mimeTypesToRegister = mimeTypesToRegister || {};
}
/**
* Creates a production-mode CompilerHost from the previously saved
* configuration
*
* @param {string} rootCacheDir The root directory to use for the cache. This
* cache must have cache information saved via
* {@link saveConfiguration}
*
* @param {string} appRoot The top-level directory for your application (i.e.
* the one which has your package.json).
*
* @param {CompilerBase} fallbackCompiler (optional) When a file is compiled
* which doesn't have a matching compiler,
* this compiler will be used instead. If
* null, will fail compilation. A good
* alternate fallback is the compiler for
* 'text/plain', which is guaranteed to be
* present.
*
* @return {Promise<CompilerHost>} A read-only CompilerHost
*/
static createReadonlyFromConfiguration(rootCacheDir, appRoot) {
let fallbackCompiler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return _asyncToGenerator(function* () {
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = yield _promise.pfs.readFile(target);
let info = JSON.parse((yield _promise.pzlib.gunzip(buf)));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, true);
let compilers = Object.keys(info.compilers).reduce(function (acc, x) {
let cur = info.compilers[x];
acc[x] = new _readOnlyCompiler2.default(cur.name, cur.compilerVersion, cur.compilerOptions, cur.inputMimeTypes);
return acc;
}, {});
return new CompilerHost(rootCacheDir, compilers, fileChangeCache, true, fallbackCompiler, null, info.mimeTypesToRegister);
})();
}
/**
* Creates a development-mode CompilerHost from the previously saved
* configuration.
*
* @param {string} rootCacheDir The root directory to use for the cache. This
* cache must have cache information saved via
* {@link saveConfiguration}
*
* @param {string} appRoot The top-level directory for your application (i.e.
* the one which has your package.json).
*
* @param {Object} compilersByMimeType an Object whose keys are input MIME
* types and whose values are instances
* of CompilerBase. Create this via the
* {@link createCompilers} method in
* config-parser.
*
* @param {CompilerBase} fallbackCompiler (optional) When a file is compiled
* which doesn't have a matching compiler,
* this compiler will be used instead. If
* null, will fail compilation. A good
* alternate fallback is the compiler for
* 'text/plain', which is guaranteed to be
* present.
*
* @return {Promise<CompilerHost>} A read-only CompilerHost
*/
static createFromConfiguration(rootCacheDir, appRoot, compilersByMimeType) {
let fallbackCompiler = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
return _asyncToGenerator(function* () {
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = yield _promise.pfs.readFile(target);
let info = JSON.parse((yield _promise.pzlib.gunzip(buf)));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, false);
Object.keys(info.compilers).forEach(function (x) {
let cur = info.compilers[x];
compilersByMimeType[x].compilerOptions = cur.compilerOptions;
});
return new CompilerHost(rootCacheDir, compilersByMimeType, fileChangeCache, false, fallbackCompiler, null, info.mimeTypesToRegister);
})();
}
/**
* Saves the current compiler configuration to a file that
* {@link createReadonlyFromConfiguration} can use to recreate the current
* compiler environment
*
* @return {Promise} Completion
*/
saveConfiguration() {
var _this = this;
return _asyncToGenerator(function* () {
let serializedCompilerOpts = Object.keys(_this.compilersByMimeType).reduce(function (acc, x) {
let compiler = _this.compilersByMimeType[x];
let Klass = Object.getPrototypeOf(compiler).constructor;
let val = {
name: Klass.name,
inputMimeTypes: Klass.getInputMimeTypes(),
compilerOptions: compiler.compilerOptions,
compilerVersion: compiler.getCompilerVersion()
};
acc[x] = val;
return acc;
}, {});
let info = {
fileChangeCache: _this.fileChangeCache.getSavedData(),
compilers: serializedCompilerOpts,
mimeTypesToRegister: _this.mimeTypesToRegister
};
let target = _path2.default.join(_this.rootCacheDir, 'compiler-info.json.gz');
let buf = yield _promise.pzlib.gzip(new Buffer(JSON.stringify(info)));
yield _promise.pfs.writeFile(target, buf);
})();
}
/**
* Compiles a file and returns the compiled result.
*
* @param {string} filePath The path to the file to compile
*
* @return {Promise<object>} An Object with the compiled result
*
* @property {Object} hashInfo The hash information returned from getHashForPath
* @property {string} code The source code if the file was a text file
* @property {Buffer} binaryData The file if it was a binary file
* @property {string} mimeType The MIME type saved in the cache.
* @property {string[]} dependentFiles The dependent files returned from
* compiling the file, if any.
*/
compile(filePath) {
var _this2 = this;
return _asyncToGenerator(function* () {
let ret = yield _this2.readOnlyMode ? _this2.compileReadOnly(filePath) : _this2.fullCompile(filePath);
if (ret.mimeType === 'application/javascript') {
_this2.mimeTypesToRegister[_mimeTypes2.default.lookup(filePath)] = true;
}
return ret;
})();
}
/**
* Handles compilation in read-only mode
*
* @private
*/
compileReadOnly(filePath) {
var _this3 = this;
return _asyncToGenerator(function* () {
// We guarantee that node_modules are always shipped directly
let type = _mimeTypes2.default.lookup(filePath);
if (_fileChangeCache2.default.isInNodeModules(filePath)) {
return {
mimeType: type || 'application/javascript',
code: yield _promise.pfs.readFile(filePath, 'utf8')
};
}
let hashInfo = yield _this3.fileChangeCache.getHashForPath(filePath);
// NB: Here, we're basically only using the compiler here to find
// the appropriate CompileCache
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? _this3.getPassthroughCompiler() : _this3.compilersByMimeType[type || '__lolnothere'];
// NB: We don't put this into shouldPassthrough because Inline HTML
// compiler is technically of type finalForms (i.e. a browser can
// natively handle this content), yet its compiler is
// InlineHtmlCompiler. However, we still want to catch standard CSS files
// which will be processed by PassthroughCompiler.
if (finalForms[type] && !compiler) {
compiler = _this3.getPassthroughCompiler();
}
if (!compiler) {
compiler = _this3.fallbackCompiler;
var _ref = yield compiler.get(filePath);
let code = _ref.code,
binaryData = _ref.binaryData,
mimeType = _ref.mimeType;
return { code: code || binaryData, mimeType };
}
let cache = _this3.cachesForCompilers.get(compiler);
var _ref2 = yield cache.get(filePath);
let code = _ref2.code,
binaryData = _ref2.binaryData,
mimeType = _ref2.mimeType;
code = code || binaryData;
if (!code || !mimeType) {
throw new Error(`Asked to compile ${filePath} in production, is this file not precompiled?`);
}
return { code, mimeType };
})();
}
/**
* Handles compilation in read-write mode
*
* @private
*/
fullCompile(filePath) {
var _this4 = this;
return _asyncToGenerator(function* () {
d(`Compiling ${filePath}`);
let type = _mimeTypes2.default.lookup(filePath);
(0, _browserSignal.send)('electron-compile-compiled-file', { filePath, mimeType: type });
let hashInfo = yield _this4.fileChangeCache.getHashForPath(filePath);
if (hashInfo.isInNodeModules) {
let code = hashInfo.sourceCode || (yield _promise.pfs.readFile(filePath, 'utf8'));
code = yield CompilerHost.fixNodeModulesSourceMapping(code, filePath, _this4.fileChangeCache.appRoot);
return { code, mimeType: type };
}
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? _this4.getPassthroughCompiler() : _this4.compilersByMimeType[type || '__lolnothere'];
if (!compiler) {
d(`Falling back to passthrough compiler for ${filePath}`);
compiler = _this4.fallbackCompiler;
}
if (!compiler) {
throw new Error(`Couldn't find a compiler for ${filePath}`);
}
let cache = _this4.cachesForCompilers.get(compiler);
return yield cache.getOrFetch(filePath, function (filePath, hashInfo) {
return _this4.compileUncached(filePath, hashInfo, compiler);
});
})();
}
/**
* Handles invoking compilers independent of caching
*
* @private
*/
compileUncached(filePath, hashInfo, compiler) {
var _this5 = this;
return _asyncToGenerator(function* () {
let inputMimeType = _mimeTypes2.default.lookup(filePath);
if (hashInfo.isFileBinary) {
return {
binaryData: hashInfo.binaryData || (yield _promise.pfs.readFile(filePath)),
mimeType: inputMimeType,
dependentFiles: []
};
}
let ctx = {};
let code = hashInfo.sourceCode || (yield _promise.pfs.readFile(filePath, 'utf8'));
if (!(yield compiler.shouldCompileFile(code, ctx))) {
d(`Compiler returned false for shouldCompileFile: ${filePath}`);
return { code, mimeType: _mimeTypes2.default.lookup(filePath), dependentFiles: [] };
}
let dependentFiles = yield compiler.determineDependentFiles(code, filePath, ctx);
d(`Using compiler options: ${JSON.stringify(compiler.compilerOptions)}`);
let result = yield compiler.compile(code, filePath, ctx);
let shouldInlineHtmlify = inputMimeType !== 'text/html' && result.mimeType === 'text/html';
let isPassthrough = result.mimeType === 'text/plain' || !result.mimeType || CompilerHost.shouldPassthrough(hashInfo);
if (finalForms[result.mimeType] && !shouldInlineHtmlify || isPassthrough) {
// Got something we can use in-browser, let's return it
return Object.assign(result, { dependentFiles });
} else {
d(`Recursively compiling result of ${filePath} with non-final MIME type ${result.mimeType}, input was ${inputMimeType}`);
hashInfo = Object.assign({ sourceCode: result.code, mimeType: result.mimeType }, hashInfo);
compiler = _this5.compilersByMimeType[result.mimeType || '__lolnothere'];
if (!compiler) {
d(`Recursive compile failed - intermediate result: ${JSON.stringify(result)}`);
throw new Error(`Compiling ${filePath} resulted in a MIME type of ${result.mimeType}, which we don't know how to handle`);
}
return yield _this5.compileUncached(`${filePath}.${_mimeTypes2.default.extension(result.mimeType || 'txt')}`, hashInfo, compiler);
}
})();
}
/**
* Pre-caches an entire directory of files recursively. Usually used for
* building custom compiler tooling.
*
* @param {string} rootDirectory The top-level directory to compile
*
* @param {Function} shouldCompile (optional) A Function which allows the
* caller to disable compiling certain files.
* It takes a fully-qualified path to a file,
* and should return a Boolean.
*
* @return {Promise} Completion.
*/
compileAll(rootDirectory) {
var _this6 = this;
let shouldCompile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return _asyncToGenerator(function* () {
let should = shouldCompile || function () {
return true;
};
yield (0, _forAllFiles.forAllFiles)(rootDirectory, function (f) {
if (!should(f)) return;
d(`Compiling ${f}`);
return _this6.compile(f, _this6.compilersByMimeType);
});
})();
}
listenToCompileEvents() {
return (0, _browserSignal.listen)('electron-compile-compiled-file').map((_ref3) => {
var _ref4 = _slicedToArray(_ref3, 1);
let x = _ref4[0];
return x;
});
}
/*
* Sync Methods
*/
compileSync(filePath) {
let ret = this.readOnlyMode ? this.compileReadOnlySync(filePath) : this.fullCompileSync(filePath);
if (ret.mimeType === 'application/javascript') {
this.mimeTypesToRegister[_mimeTypes2.default.lookup(filePath)] = true;
}
return ret;
}
static createReadonlyFromConfigurationSync(rootCacheDir, appRoot) {
let fallbackCompiler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = _fs2.default.readFileSync(target);
let info = JSON.parse(_zlib2.default.gunzipSync(buf));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, true);
let compilers = Object.keys(info.compilers).reduce((acc, x) => {
let cur = info.compilers[x];
acc[x] = new _readOnlyCompiler2.default(cur.name, cur.compilerVersion, cur.compilerOptions, cur.inputMimeTypes);
return acc;
}, {});
return new CompilerHost(rootCacheDir, compilers, fileChangeCache, true, fallbackCompiler, null, info.mimeTypesToRegister);
}
static createFromConfigurationSync(rootCacheDir, appRoot, compilersByMimeType) {
let fallbackCompiler = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = _fs2.default.readFileSync(target);
let info = JSON.parse(_zlib2.default.gunzipSync(buf));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, false);
Object.keys(info.compilers).forEach(x => {
let cur = info.compilers[x];
compilersByMimeType[x].compilerOptions = cur.compilerOptions;
});
return new CompilerHost(rootCacheDir, compilersByMimeType, fileChangeCache, false, fallbackCompiler, null, info.mimeTypesToRegister);
}
saveConfigurationSync() {
let serializedCompilerOpts = Object.keys(this.compilersByMimeType).reduce((acc, x) => {
let compiler = this.compilersByMimeType[x];
let Klass = Object.getPrototypeOf(compiler).constructor;
let val = {
name: Klass.name,
inputMimeTypes: Klass.getInputMimeTypes(),
compilerOptions: compiler.compilerOptions,
compilerVersion: compiler.getCompilerVersion()
};
acc[x] = val;
return acc;
}, {});
let info = {
fileChangeCache: this.fileChangeCache.getSavedData(),
compilers: serializedCompilerOpts,
mimeTypesToRegister: this.mimeTypesToRegister
};
let target = _path2.default.join(this.rootCacheDir, 'compiler-info.json.gz');
let buf = _zlib2.default.gzipSync(new Buffer(JSON.stringify(info)));
_fs2.default.writeFileSync(target, buf);
}
compileReadOnlySync(filePath) {
// We guarantee that node_modules are always shipped directly
let type = _mimeTypes2.default.lookup(filePath);
if (_fileChangeCache2.default.isInNodeModules(filePath)) {
return {
mimeType: type || 'application/javascript',
code: _fs2.default.readFileSync(filePath, 'utf8')
};
}
let hashInfo = this.fileChangeCache.getHashForPathSync(filePath);
// We guarantee that node_modules are always shipped directly
if (hashInfo.isInNodeModules) {
return {
mimeType: type,
code: hashInfo.sourceCode || _fs2.default.readFileSync(filePath, 'utf8')
};
}
// NB: Here, we're basically only using the compiler here to find
// the appropriate CompileCache
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? this.getPassthroughCompiler() : this.compilersByMimeType[type || '__lolnothere'];
// NB: We don't put this into shouldPassthrough because Inline HTML
// compiler is technically of type finalForms (i.e. a browser can
// natively handle this content), yet its compiler is
// InlineHtmlCompiler. However, we still want to catch standard CSS files
// which will be processed by PassthroughCompiler.
if (finalForms[type] && !compiler) {
compiler = this.getPassthroughCompiler();
}
if (!compiler) {
compiler = this.fallbackCompiler;
var _compiler$getSync = compiler.getSync(filePath);
let code = _compiler$getSync.code,
binaryData = _compiler$getSync.binaryData,
mimeType = _compiler$getSync.mimeType;
return { code: code || binaryData, mimeType };
}
let cache = this.cachesForCompilers.get(compiler);
var _cache$getSync = cache.getSync(filePath);
let code = _cache$getSync.code,
binaryData = _cache$getSync.binaryData,
mimeType = _cache$getSync.mimeType;
code = code || binaryData;
if (!code || !mimeType) {
throw new Error(`Asked to compile ${filePath} in production, is this file not precompiled?`);
}
return { code, mimeType };
}
fullCompileSync(filePath) {
d(`Compiling ${filePath}`);
let type = _mimeTypes2.default.lookup(filePath);
(0, _browserSignal.send)('electron-compile-compiled-file', { filePath, mimeType: type });
let hashInfo = this.fileChangeCache.getHashForPathSync(filePath);
if (hashInfo.isInNodeModules) {
let code = hashInfo.sourceCode || _fs2.default.readFileSync(filePath, 'utf8');
code = CompilerHost.fixNodeModulesSourceMappingSync(code, filePath, this.fileChangeCache.appRoot);
return { code, mimeType: type };
}
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? this.getPassthroughCompiler() : this.compilersByMimeType[type || '__lolnothere'];
if (!compiler) {
d(`Falling back to passthrough compiler for ${filePath}`);
compiler = this.fallbackCompiler;
}
if (!compiler) {
throw new Error(`Couldn't find a compiler for ${filePath}`);
}
let cache = this.cachesForCompilers.get(compiler);
return cache.getOrFetchSync(filePath, (filePath, hashInfo) => this.compileUncachedSync(filePath, hashInfo, compiler));
}
compileUncachedSync(filePath, hashInfo, compiler) {
let inputMimeType = _mimeTypes2.default.lookup(filePath);
if (hashInfo.isFileBinary) {
return {
binaryData: hashInfo.binaryData || _fs2.default.readFileSync(filePath),
mimeType: inputMimeType,
dependentFiles: []
};
}
let ctx = {};
let code = hashInfo.sourceCode || _fs2.default.readFileSync(filePath, 'utf8');
if (!compiler.shouldCompileFileSync(code, ctx)) {
d(`Compiler returned false for shouldCompileFile: ${filePath}`);
return { code, mimeType: _mimeTypes2.default.lookup(filePath), dependentFiles: [] };
}
let dependentFiles = compiler.determineDependentFilesSync(code, filePath, ctx);
let result = compiler.compileSync(code, filePath, ctx);
let shouldInlineHtmlify = inputMimeType !== 'text/html' && result.mimeType === 'text/html';
let isPassthrough = result.mimeType === 'text/plain' || !result.mimeType || CompilerHost.shouldPassthrough(hashInfo);
if (finalForms[result.mimeType] && !shouldInlineHtmlify || isPassthrough) {
// Got something we can use in-browser, let's return it
return Object.assign(result, { dependentFiles });
} else {
d(`Recursively compiling result of ${filePath} with non-final MIME type ${result.mimeType}, input was ${inputMimeType}`);
hashInfo = Object.assign({ sourceCode: result.code, mimeType: result.mimeType }, hashInfo);
compiler = this.compilersByMimeType[result.mimeType || '__lolnothere'];
if (!compiler) {
d(`Recursive compile failed - intermediate result: ${JSON.stringify(result)}`);
throw new Error(`Compiling ${filePath} resulted in a MIME type of ${result.mimeType}, which we don't know how to handle`);
}
return this.compileUncachedSync(`${filePath}.${_mimeTypes2.default.extension(result.mimeType || 'txt')}`, hashInfo, compiler);
}
}
compileAllSync(rootDirectory) {
let shouldCompile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let should = shouldCompile || function () {
return true;
};
(0, _forAllFiles.forAllFilesSync)(rootDirectory, f => {
if (!should(f)) return;
return this.compileSync(f, this.compilersByMimeType);
});
}
/*
* Other stuff
*/
/**
* Returns the passthrough compiler
*
* @private
*/
getPassthroughCompiler() {
return this.compilersByMimeType['text/plain'];
}
/**
* Determines whether we should even try to compile the content. Note that in
* some cases, content will still be in cache even if this returns true, and
* in other cases (isInNodeModules), we'll know explicitly to not even bother
* looking in the cache.
*
* @private
*/
static shouldPassthrough(hashInfo) {
return hashInfo.isMinified || hashInfo.isInNodeModules || hashInfo.hasSourceMap || hashInfo.isFileBinary;
}
/**
* Look at the code of a node modules and see the sourceMapping path.
* If there is any, check the path and try to fix it with and
* root relative path.
* @private
*/
static fixNodeModulesSourceMapping(sourceCode, sourcePath, appRoot) {
return _asyncToGenerator(function* () {
let regexSourceMapping = /\/\/#.*sourceMappingURL=(?!data:)([^"'].*)/i;
let sourceMappingCheck = sourceCode.match(regexSourceMapping);
if (sourceMappingCheck && sourceMappingCheck[1] && sourceMappingCheck[1] !== '') {
let sourceMapPath = sourceMappingCheck[1];
try {
yield _promise.pfs.stat(sourceMapPath);
} catch (error) {
let normRoot = _path2.default.normalize(appRoot);
let absPathToModule = _path2.default.dirname(sourcePath.replace(normRoot, '').substring(1));
let newMapPath = _path2.default.join(absPathToModule, sourceMapPath);
return sourceCode.replace(regexSourceMapping, `//# sourceMappingURL=${newMapPath}`);
}
}
return sourceCode;
})();
}
/**
* Look at the code of a node modules and see the sourceMapping path.
* If there is any, check the path and try to fix it with and
* root relative path.
* @private
*/
static fixNodeModulesSourceMappingSync(sourceCode, sourcePath, appRoot) {
let regexSourceMapping = /\/\/#.*sourceMappingURL=(?!data:)([^"'].*)/i;
let sourceMappingCheck = sourceCode.match(regexSourceMapping);
if (sourceMappingCheck && sourceMappingCheck[1] && sourceMappingCheck[1] !== '') {
let sourceMapPath = sourceMappingCheck[1];
try {
_fs2.default.statSync(sourceMapPath);
} catch (error) {
let normRoot = _path2.default.normalize(appRoot);
let absPathToModule = _path2.default.dirname(sourcePath.replace(normRoot, '').substring(1));
let newMapPath = _path2.default.join(absPathToModule, sourceMapPath);
return sourceCode.replace(regexSourceMapping, `//# sourceMappingURL=${newMapPath}`);
}
}
return sourceCode;
}
}
exports.default = CompilerHost;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21waWxlci1ob3N0LmpzIl0sIm5hbWVzIjpbImQiLCJyZXF1aXJlIiwiaW5pdCIsImZpbmFsRm9ybXMiLCJDb21waWxlckhvc3QiLCJjb25zdHJ1Y3RvciIsInJvb3RDYWNoZURpciIsImNvbXBpbGVycyIsImZpbGVDaGFuZ2VDYWNoZSIsInJlYWRPbmx5TW9kZSIsImZhbGxiYWNrQ29tcGlsZXIiLCJzb3VyY2VNYXBQYXRoIiwibWltZVR5cGVzVG9SZWdpc3RlciIsImNvbXBpbGVyc0J5TWltZVR5cGUiLCJPYmplY3QiLCJhc3NpZ24iLCJhcHBSb290IiwiY2FjaGVzRm9yQ29tcGlsZXJzIiwia2V5cyIsInJlZHVjZSIsImFjYyIsIngiLCJjb21waWxlciIsImhhcyIsInNldCIsIkNvbXBpbGVDYWNoZSIsImNyZWF0ZUZyb21Db21waWxlciIsIk1hcCIsImNyZWF0ZVJlYWRvbmx5RnJvbUNvbmZpZ3VyYXRpb24iLCJ0YXJnZXQiLCJwYXRoIiwiam9pbiIsImJ1ZiIsInBmcyIsInJlYWRGaWxlIiwiaW5mbyIsIkpTT04iLCJwYXJzZSIsInB6bGliIiwiZ3VuemlwIiwiRmlsZUNoYW5nZWRDYWNoZSIsImxvYWRGcm9tRGF0YSIsImN1ciIsIlJlYWRPbmx5Q29tcGlsZXIiLCJuYW1lIiwiY29tcGlsZXJWZXJzaW9uIiwiY29tcGlsZXJPcHRpb25zIiwiaW5wdXRNaW1lVHlwZXMiLCJjcmVhdGVGcm9tQ29uZmlndXJhdGlvbiIsImZvckVhY2giLCJzYXZlQ29uZmlndXJhdGlvbiIsInNlcmlhbGl6ZWRDb21waWxlck9wdHMiLCJLbGFzcyIsImdldFByb3RvdHlwZU9mIiwidmFsIiwiZ2V0SW5wdXRNaW1lVHlwZXMiLCJnZXRDb21waWxlclZlcnNpb24iLCJnZXRTYXZlZERhdGEiLCJnemlwIiwiQnVmZmVyIiwic3RyaW5naWZ5Iiwid3JpdGVGaWxlIiwiY29tcGlsZSIsImZpbGVQYXRoIiwicmV0IiwiY29tcGlsZVJlYWRPbmx5IiwiZnVsbENvbXBpbGUiLCJtaW1lVHlwZSIsIm1pbWVUeXBlcyIsImxvb2t1cCIsInR5cGUiLCJpc0luTm9kZU1vZHVsZXMiLCJjb2RlIiwiaGFzaEluZm8iLCJnZXRIYXNoRm9yUGF0aCIsInNob3VsZFBhc3N0aHJvdWdoIiwiZ2V0UGFzc3Rocm91Z2hDb21waWxlciIsImdldCIsImJpbmFyeURhdGEiLCJjYWNoZSIsIkVycm9yIiwic291cmNlQ29kZSIsImZpeE5vZGVNb2R1bGVzU291cmNlTWFwcGluZyIsImdldE9yRmV0Y2giLCJjb21waWxlVW5jYWNoZWQiLCJpbnB1dE1pbWVUeXBlIiwiaXNGaWxlQmluYXJ5IiwiZGVwZW5kZW50RmlsZXMiLCJjdHgiLCJzaG91bGRDb21waWxlRmlsZSIsImRldGVybWluZURlcGVuZGVudEZpbGVzIiwicmVzdWx0Iiwic2hvdWxkSW5saW5lSHRtbGlmeSIsImlzUGFzc3Rocm91Z2giLCJleHRlbnNpb24iLCJjb21waWxlQWxsIiwicm9vdERpcmVjdG9yeSIsInNob3VsZENvbXBpbGUiLCJzaG91bGQiLCJmIiwibGlzdGVuVG9Db21waWxlRXZlbnRzIiwibWFwIiwiY29tcGlsZVN5bmMiLCJjb21waWxlUmVhZE9ubHlTeW5jIiwiZnVsbENvbXBpbGVTeW5jIiwiY3JlYXRlUmVhZG9ubHlGcm9tQ29uZmlndXJhdGlvblN5bmMiLCJmcyIsInJlYWRGaWxlU3luYyIsInpsaWIiLCJndW56aXBTeW5jIiwiY3JlYXRlRnJvbUNvbmZpZ3VyYXRpb25TeW5jIiwic2F2ZUNvbmZpZ3VyYXRpb25TeW5jIiwiZ3ppcFN5bmMiLCJ3cml0ZUZpbGVTeW5jIiwiZ2V0SGFzaEZvclBhdGhTeW5jIiwiZ2V0U3luYyIsImZpeE5vZGVNb2R1bGVzU291cmNlTWFwcGluZ1N5bmMiLCJnZXRPckZldGNoU3luYyIsImNvbXBpbGVVbmNhY2hlZFN5bmMiLCJzaG91bGRDb21waWxlRmlsZVN5bmMiLCJkZXRlcm1pbmVEZXBlbmRlbnRGaWxlc1N5bmMiLCJjb21waWxlQWxsU3luYyIsImlzTWluaWZpZWQiLCJoYXNTb3VyY2VNYXAiLCJzb3VyY2VQYXRoIiwicmVnZXhTb3VyY2VNYXBwaW5nIiwic291cmNlTWFwcGluZ0NoZWNrIiwibWF0Y2giLCJzdGF0IiwiZXJyb3IiLCJub3JtUm9vdCIsIm5vcm1hbGl6ZSIsImFic1BhdGhUb01vZHVsZSIsImRpcm5hbWUiLCJyZXBsYWNlIiwic3Vic3RyaW5nIiwibmV3TWFwUGF0aCIsInN0YXRTeW5jIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBRUE7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBSUE7Ozs7OztBQUZBLE1BQU1BLElBQUlDLFFBQVEsT0FBUixFQUFpQixnQ0FBakIsQ0FBVjs7QUFJQUEsUUFBUSxrQkFBUixFQUE0QkMsSUFBNUI7O0FBRUE7QUFDQSxNQUFNQyxhQUFhO0FBQ2pCLHFCQUFtQixJQURGO0FBRWpCLDRCQUEwQixJQUZUO0FBR2pCLGVBQWEsSUFISTtBQUlqQixjQUFZLElBSks7QUFLakIsbUJBQWlCLElBTEE7QUFNakIsc0JBQW9CO0FBTkgsQ0FBbkI7O0FBU0E7Ozs7Ozs7Ozs7Ozs7O0FBY2UsTUFBTUMsWUFBTixDQUFtQjtBQUNoQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBOEJBQyxjQUFZQyxZQUFaLEVBQTBCQyxTQUExQixFQUFxQ0MsZUFBckMsRUFBc0RDLFlBQXRELEVBQStJO0FBQUEsUUFBM0VDLGdCQUEyRSx1RUFBeEQsSUFBd0Q7QUFBQSxRQUFsREMsYUFBa0QsdUVBQWxDLElBQWtDO0FBQUEsUUFBNUJDLG1CQUE0Qix1RUFBTixJQUFNOztBQUM3SSxRQUFJQyxzQkFBc0JDLE9BQU9DLE1BQVAsQ0FBYyxFQUFkLEVBQWtCUixTQUFsQixDQUExQjtBQUNBTyxXQUFPQyxNQUFQLENBQWMsSUFBZCxFQUFvQixFQUFDVCxZQUFELEVBQWVPLG1CQUFmLEVBQW9DTCxlQUFwQyxFQUFxREMsWUFBckQsRUFBbUVDLGdCQUFuRSxFQUFwQjtB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