morpha
Version:
A Web-IDE or Desktop-IDE creator.
204 lines (172 loc) • 5.74 kB
JavaScript
;
var _defineProperty = require('babel-runtime/core-js/object/define-property');
var _defineProperty2 = _interopRequireDefault(_defineProperty);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var path = require('path');
var fs = require('fs-plus');
var rmrf = require('rmrf');
var COMPILERS = {
'.js': require('./babel'),
'.jsx': require('./babel')
// todo support less compiler
};
var cacheStats = {};
var cacheDirectory = null;
exports.setCacheDirectory = function (directory) {
cacheDirectory = directory;
};
exports.clearCacheFromDirectory = function () {
if (cacheDirectory) rmrf(cacheDirectory);
};
exports.getCacheStats = function () {
return cacheStats;
};
exports.resetCacheStats = function () {
(0, _keys2.default)(COMPILERS).forEach(function (extension) {
cacheStats[extension] = {
hits: 0,
misses: 0
};
});
};
exports.addPathToCache = function (filePath) {
var extension = path.extname(filePath);
var compiler = COMPILERS[extension];
if (compiler) {
compileFileAtPath(compiler, filePath, extension);
}
};
function compileFileAtPath(compiler, filePath, extension) {
var sourceCode = fs.readFileSync(filePath, 'utf8');
if (compiler.shouldCompile(sourceCode, filePath)) {
var cachePath = compiler.getCachePath(sourceCode, filePath);
var compiledCode = readCachedJavascript(cachePath);
if (compiledCode !== null) {
cacheStats[extension].hits++;
} else {
cacheStats[extension].misses++;
compiledCode = addSourceURL(compiler.compile(sourceCode, filePath), filePath);
writeCachedJavascript(cachePath, compiledCode);
}
return compiledCode;
}
return sourceCode;
}
function readCachedJavascript(relativeCachePath) {
var cachePath = path.join(cacheDirectory, relativeCachePath);
if (fs.isFileSync(cachePath)) {
try {
return fs.readFileSync(cachePath, 'utf8');
} catch (error) {}
}
return null;
}
function writeCachedJavascript(relativeCachePath, code) {
var cachePath = path.join(cacheDirectory, relativeCachePath);
fs.writeFileSync(cachePath, code, 'utf8');
}
function addSourceURL(jsCode, filePath) {
if (process.platform === 'win32') {
filePath = '/' + path.resolve(filePath).replace(/\\/g, '/');
}
return jsCode + '\n' + '//# sourceURL=' + encodeURI(filePath) + '\n';
}
var INLINE_SOURCE_MAP_REGEXP = /\/\/[#@]\s*sourceMappingURL=([^'"\n]+)\s*$/mg;
require('source-map-support').install({
handleUncaughtExceptions: false,
// Most of this logic is the same as the default implementation in the
// source-map-support module, but we've overridden it to read the javascript
// code from our cache directory.
retrieveSourceMap: function retrieveSourceMap(filePath) {
if (!cacheDirectory || !fs.isFileSync(filePath)) {
return null;
}
var sourceCode = void 0;
var fileData = void 0;
try {
sourceCode = fs.readFileSync(filePath, 'utf8');
} catch (error) {
console.warn('Error reading source file', error.stack);
return null;
}
var compiler = COMPILERS[path.extname(filePath)];
try {
fileData = readCachedJavascript(compiler.getCachePath(sourceCode, filePath));
} catch (error) {
console.warn('Error reading compiled file', error.stack);
return null;
}
if (!fileData) {
return null;
}
var match = void 0,
lastMatch = void 0,
sourceMap = void 0;
INLINE_SOURCE_MAP_REGEXP.lastIndex = 0;
/* eslint-disable no-cond-assign*/
while (match = INLINE_SOURCE_MAP_REGEXP.exec(fileData)) {
lastMatch = match;
}
if (!lastMatch) {
return null;
}
/* eslint-enable no-cond-assign*/
var sourceMappingURL = lastMatch[1];
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
try {
sourceMap = JSON.parse(new Buffer(rawData, 'base64'));
} catch (error) {
console.warn('Error parsing source map', error.stack);
return null;
}
return {
map: sourceMap,
url: null
};
}
});
var prepareStackTraceWithSourceMapping = Error.prepareStackTrace;
var prepareStackTrace = prepareStackTraceWithSourceMapping;
function prepareStackTraceWithRawStackAssignment(error, frames) {
if (error.rawStack) {
// avoid infinite recursion
return prepareStackTraceWithSourceMapping(error, frames);
}
error.rawStack = frames;
return prepareStackTrace(error, frames);
}
Error.stackTraceLimit = 30;
Object.defineProperty(Error, 'prepareStackTrace', {
get: function get() {
return prepareStackTraceWithRawStackAssignment;
},
set: function set(newValue) {
prepareStackTrace = newValue;
process.nextTick(function () {
prepareStackTrace = prepareStackTraceWithSourceMapping;
});
}
});
/* eslint-disable no-unused-expressions, no-extend-native */
Error.prototype.getRawStack = function () {
// Access this.stack to ensure prepareStackTrace has been run on this error
// because it assigns this.rawStack as a side-effect
this.stack;
return this.rawStack;
};
/* eslint-enable no-unused-expressions, no-extend-native */
(0, _keys2.default)(COMPILERS).forEach(function (extension) {
var compiler = COMPILERS[extension];
(0, _defineProperty2.default)(require.extensions, extension, {
enumerable: true,
writable: false,
value: function value(module, filePath) {
// TODO add module parent tree
var code = compileFileAtPath(compiler, filePath, extension);
return module._compile(code, filePath);
}
});
});
exports.resetCacheStats();