mirror of https://github.com/lukechilds/ava.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.0 KiB
96 lines
3.0 KiB
var fs = require('fs');
|
|
var path = require('path');
|
|
var cachingTransform = require('caching-transform');
|
|
var md5Hex = require('md5-hex');
|
|
var stripBom = require('strip-bom');
|
|
|
|
module.exports = CachingPrecompiler;
|
|
|
|
function CachingPrecompiler(cacheDir) {
|
|
if (!(this instanceof CachingPrecompiler)) {
|
|
throw new TypeError('Class constructor CachingPrecompiler cannot be invoked without \'new\'');
|
|
}
|
|
|
|
this.cacheDir = cacheDir;
|
|
this.filenameToHash = {};
|
|
this.transform = this._createTransform();
|
|
}
|
|
|
|
CachingPrecompiler.prototype._factory = function (cacheDir) {
|
|
// This factory method is only called once per process, and only as needed, to defer loading expensive dependencies.
|
|
var babel = require('babel-core');
|
|
var convertSourceMap = require('convert-source-map');
|
|
var presetStage2 = require('babel-preset-stage-2');
|
|
var presetES2015 = require('babel-preset-es2015');
|
|
var transformRuntime = require('babel-plugin-transform-runtime');
|
|
|
|
var powerAssert = this._createEspowerPlugin(babel);
|
|
|
|
function buildOptions(filename, code) {
|
|
// Extract existing source maps from the code.
|
|
var sourceMap = convertSourceMap.fromSource(code) || convertSourceMap.fromMapFileSource(code, path.dirname(filename));
|
|
|
|
return {
|
|
presets: [presetStage2, presetES2015],
|
|
plugins: [powerAssert, transformRuntime],
|
|
filename: filename,
|
|
sourceMaps: true,
|
|
ast: false,
|
|
babelrc: false,
|
|
inputSourceMap: sourceMap && sourceMap.toObject()
|
|
};
|
|
}
|
|
|
|
return function (code, filename, hash) {
|
|
code = code.toString();
|
|
var options = buildOptions(filename, code);
|
|
var result = babel.transform(code, options);
|
|
var mapFile = path.join(cacheDir, hash + '.map');
|
|
fs.writeFileSync(mapFile, JSON.stringify(result.map));
|
|
return result.code;
|
|
};
|
|
};
|
|
|
|
CachingPrecompiler.prototype._createEspowerPlugin = function (babel) {
|
|
var createEspowerPlugin = require('babel-plugin-espower/create');
|
|
var enhanceAssert = require('./enhance-assert');
|
|
|
|
// initialize power-assert
|
|
return createEspowerPlugin(babel, {
|
|
patterns: enhanceAssert.PATTERNS
|
|
});
|
|
};
|
|
|
|
CachingPrecompiler.prototype._createTransform = function () {
|
|
return cachingTransform({
|
|
factory: this._factory.bind(this),
|
|
cacheDir: this.cacheDir,
|
|
salt: new Buffer(JSON.stringify({
|
|
'babel-plugin-espower': require('babel-plugin-espower/package.json').version,
|
|
'ava': require('../package.json').version,
|
|
'babel-core': require('babel-core/package.json').version
|
|
})),
|
|
ext: '.js',
|
|
hash: this._hash.bind(this)
|
|
});
|
|
};
|
|
|
|
CachingPrecompiler.prototype._hash = function (code, filename, salt) {
|
|
var hash = md5Hex([code, filename, salt]);
|
|
this.filenameToHash[filename] = hash;
|
|
return hash;
|
|
};
|
|
|
|
CachingPrecompiler.prototype.precompileFile = function (filename) {
|
|
if (!this.filenameToHash[filename]) {
|
|
this.transform(stripBom(fs.readFileSync(filename)), filename);
|
|
}
|
|
|
|
return this.filenameToHash[filename];
|
|
};
|
|
|
|
CachingPrecompiler.prototype.generateHashForFile = function (filename) {
|
|
var hash = {};
|
|
hash[filename] = this.precompileFile(filename);
|
|
return hash;
|
|
};
|
|
|