diff --git a/api.js b/api.js index 9c6e775d6..78f0e9c0d 100644 --- a/api.js +++ b/api.js @@ -16,6 +16,7 @@ const arrify = require('arrify'); const ms = require('ms'); const babelConfigHelper = require('./lib/babel-config'); const CachingPrecompiler = require('./lib/caching-precompiler'); +const NativeCachingPrecompiler = require('./lib/native-caching-precompiler'); const RunStatus = require('./lib/run-status'); const AvaError = require('./lib/ava-error'); const AvaFiles = require('./lib/ava-files'); @@ -118,13 +119,21 @@ class Api extends EventEmitter { this.options.cacheDir = cacheDir; const isPowerAssertEnabled = this.options.powerAssert !== false; + const compileJavascriptFiles = this.options.compileJavascriptFiles !== false; return babelConfigHelper.build(this.options.projectDir, cacheDir, this.options.babelConfig, isPowerAssertEnabled) .then(result => { - this.precompiler = new CachingPrecompiler({ - path: cacheDir, - getBabelOptions: result.getOptions, - babelCacheKeys: result.cacheKeys - }); + if (compileJavascriptFiles) { + this.precompiler = new CachingPrecompiler({ + path: cacheDir, + getBabelOptions: result.getOptions, + babelCacheKeys: result.cacheKeys + }); + } else { + this.precompiler = new NativeCachingPrecompiler({ + path: cacheDir, + babelCacheKeys: result.cacheKeys + }); + } }); } @@ -262,7 +271,6 @@ class Api extends EventEmitter { const options = { runOnlyExclusive: this.options.match.length > 0 }; - resolve(test.run(options)); }).catch(err => { err.file = file; diff --git a/lib/cli.js b/lib/cli.js index 0c2c2f82f..e3aa2a1cd 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -150,7 +150,8 @@ exports.run = () => { concurrency: conf.concurrency ? parseInt(conf.concurrency, 10) : 0, updateSnapshots: conf.updateSnapshots, snapshotDir: conf.snapshotDir ? path.resolve(projectDir, conf.snapshotDir) : null, - color: conf.color + color: conf.color, + compileJavascriptFiles: conf.compileJavascriptFiles !== false }); let reporter; diff --git a/lib/native-caching-precompiler.js b/lib/native-caching-precompiler.js new file mode 100644 index 000000000..479d36427 --- /dev/null +++ b/lib/native-caching-precompiler.js @@ -0,0 +1,39 @@ +'use strict'; +const fs = require('fs'); +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'); + +class NativeCachingPrecompiler { + + constructor(options) { + autoBind(this); + this.babelCacheKeys = options.babelCacheKeys; + this.cacheDirPath = options.path; + this.fileHashes = {}; + this.transform = cachingTransform({ + cacheDir: this.cacheDirPath, + ext: '.js', + factory: () => code => code.toString(), // Native raw + salt: packageHash.sync([require.resolve('../package.json')], this.babelCacheKeys), + hash: (code, filePath, salt) => { + const hash = md5Hex([code, filePath, salt]); + this.fileHashes[filePath] = hash; + return hash; + } + }); + } + + precompileFile(filePath) { + if (!this.fileHashes[filePath]) { + const source = stripBomBuf(fs.readFileSync(filePath)); + this.transform(source, filePath); + } + + return this.fileHashes[filePath]; + } +} + +module.exports = NativeCachingPrecompiler; diff --git a/lib/process-adapter.js b/lib/process-adapter.js index 5f9c0d79d..42030c059 100644 --- a/lib/process-adapter.js +++ b/lib/process-adapter.js @@ -78,9 +78,10 @@ exports.installSourceMapSupport = () => { exports.installPrecompilerHook = () => { installPrecompiler(filename => { const precompiled = opts.precompiled[filename]; - if (precompiled) { - sourceMapCache.set(filename, path.join(cacheDir, `${precompiled}.js.map`)); + if (opts.compileJavascriptFiles) { + sourceMapCache.set(filename, path.join(cacheDir, `${precompiled}.js.map`)); + } return fs.readFileSync(path.join(cacheDir, `${precompiled}.js`), 'utf8'); } diff --git a/profile.js b/profile.js index 3067e663a..4b7ee5581 100644 --- a/profile.js +++ b/profile.js @@ -15,6 +15,7 @@ const arrify = require('arrify'); const resolveCwd = require('resolve-cwd'); const babelConfigHelper = require('./lib/babel-config'); const CachingPrecompiler = require('./lib/caching-precompiler'); +const NativeCachingPrecompiler = require('./lib/native-caching-precompiler'); const globals = require('./lib/globals'); function resolveModules(modules) { @@ -78,11 +79,19 @@ const cacheDir = findCacheDir({ babelConfigHelper.build(process.cwd(), cacheDir, conf.babel, true) .then(result => { - const precompiler = new CachingPrecompiler({ - path: cacheDir, - getBabelOptions: result.getOptions, - babelCacheKeys: result.cacheKeys - }); + let precompiler = null; + if (conf.compileJavascriptFiles) { + precompiler = new CachingPrecompiler({ + path: cacheDir, + getBabelOptions: result.getOptions, + babelCacheKeys: result.cacheKeys + }); + } else { + precompiler = new NativeCachingPrecompiler({ + path: cacheDir, + babelCacheKeys: result.cacheKeys + }); + } const precompiled = {}; precompiled[file] = precompiler.precompileFile(file);