aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ava/lib/caching-precompiler.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ava/lib/caching-precompiler.js')
-rw-r--r--node_modules/ava/lib/caching-precompiler.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/node_modules/ava/lib/caching-precompiler.js b/node_modules/ava/lib/caching-precompiler.js
new file mode 100644
index 000000000..937309bf0
--- /dev/null
+++ b/node_modules/ava/lib/caching-precompiler.js
@@ -0,0 +1,103 @@
+'use strict';
+const path = require('path');
+const fs = require('fs');
+const convertSourceMap = require('convert-source-map');
+const cachingTransform = require('caching-transform');
+const packageHash = require('package-hash');
+const stripBomBuf = require('strip-bom-buf');
+const autoBind = require('auto-bind');
+const md5Hex = require('md5-hex');
+
+function getSourceMap(filePath, code) {
+ let sourceMap = convertSourceMap.fromSource(code);
+
+ if (!sourceMap) {
+ const dirPath = path.dirname(filePath);
+ sourceMap = convertSourceMap.fromMapFileSource(code, dirPath);
+ }
+
+ if (sourceMap) {
+ sourceMap = sourceMap.toObject();
+ }
+
+ return sourceMap;
+}
+
+class CachingPrecompiler {
+ constructor(options) {
+ autoBind(this);
+
+ this.getBabelOptions = options.getBabelOptions;
+ this.babelCacheKeys = options.babelCacheKeys;
+ this.cacheDirPath = options.path;
+ this.fileHashes = {};
+ this.transform = this._createTransform();
+ }
+ precompileFile(filePath) {
+ if (!this.fileHashes[filePath]) {
+ const source = stripBomBuf(fs.readFileSync(filePath));
+ this.transform(source, filePath);
+ }
+
+ return this.fileHashes[filePath];
+ }
+ // Conditionally called by caching-transform when precompiling is required
+ _init() {
+ this.babel = require('babel-core');
+ return this._transform;
+ }
+ _transform(code, filePath, hash) {
+ code = code.toString();
+
+ let result;
+ const originalBabelDisableCache = process.env.BABEL_DISABLE_CACHE;
+ try {
+ // Disable Babel's cache. AVA has good cache management already.
+ process.env.BABEL_DISABLE_CACHE = '1';
+
+ result = this.babel.transform(code, Object.assign(this.getBabelOptions(), {
+ inputSourceMap: getSourceMap(filePath, code),
+ filename: filePath,
+ sourceMaps: true,
+ ast: false
+ }));
+ } finally {
+ // Restore the original value. It is passed to workers, where users may
+ // not want Babel's cache to be disabled.
+ process.env.BABEL_DISABLE_CACHE = originalBabelDisableCache;
+ }
+
+ // Save source map
+ const mapPath = path.join(this.cacheDirPath, `${hash}.js.map`);
+ fs.writeFileSync(mapPath, JSON.stringify(result.map));
+
+ // Append source map comment to transformed code
+ // So that other libraries (like nyc) can find the source map
+ const dirPath = path.dirname(filePath);
+ const relativeMapPath = path.relative(dirPath, mapPath);
+ const comment = convertSourceMap.generateMapFileComment(relativeMapPath);
+
+ return `${result.code}\n${comment}`;
+ }
+ _createTransform() {
+ const salt = packageHash.sync([
+ require.resolve('../package.json'),
+ require.resolve('babel-core/package.json')
+ ], this.babelCacheKeys);
+
+ return cachingTransform({
+ factory: this._init,
+ cacheDir: this.cacheDirPath,
+ hash: this._generateHash,
+ salt,
+ ext: '.js'
+ });
+ }
+ _generateHash(code, filePath, salt) {
+ const hash = md5Hex([code, filePath, salt]);
+ this.fileHashes[filePath] = hash;
+ return hash;
+ }
+}
+
+module.exports = CachingPrecompiler;