From 141b722827615788918e44e0805472f5bec4c90d Mon Sep 17 00:00:00 2001 From: Yen-Chi Chen Date: Sun, 7 Mar 2021 10:54:58 +0100 Subject: [PATCH] address feedbacks --- .../jest-transform/src/ScriptTransformer.ts | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index df579d3be78f..312df96293b3 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -26,9 +26,6 @@ import { } from 'jest-util'; import handlePotentialSyntaxError from './enhanceUnexpectedTokenMessage'; import shouldInstrument from './shouldInstrument'; -// eslint somehow complains "There should be no empty line between import groups" -// some what similar to this: https://github.com/benmosher/eslint-plugin-import/issues/1853 -//eslint-disable-next-line import/order import type { AsyncTransformer, Options, @@ -39,7 +36,6 @@ import type { TransformedSource, Transformer, } from './types'; - // Use `require` to avoid TS rootDir const {version: VERSION} = require('../package.json'); @@ -77,6 +73,7 @@ export default class ScriptTransformer { Config.Path, {transformer: Transformer; transformerConfig: unknown} >; + private readonly _transformCacheMutex: Map>; private readonly _transformConfigCache: Map; constructor( @@ -86,6 +83,7 @@ export default class ScriptTransformer { this._config = config; this._cacheFS = cacheFS; this._transformCache = new Map(); + this._transformCacheMutex = new Map(); this._transformConfigCache = new Map(); const configString = stableStringify(this._config); @@ -138,7 +136,7 @@ export default class ScriptTransformer { this._getTransformer(filename) || {}; let transformerCacheKey = undefined; - if (transformer && typeof transformer.getCacheKey === 'function') { + if (typeof transformer?.getCacheKey === 'function') { transformerCacheKey = transformer.getCacheKey(fileData, filename, { ...options, cacheFS: this._cacheFS, @@ -166,26 +164,19 @@ export default class ScriptTransformer { (await this._getTransformerAsync(filename)) || {}; let transformerCacheKey = undefined; - if (transformer && typeof transformer.getCacheKeyAsync === 'function') { - transformerCacheKey = await transformer.getCacheKeyAsync( - fileData, - filename, - { + if (transformer) { + const getCacheKey = + transformer.getCacheKeyAsync || transformer.getCacheKey; + + if (typeof getCacheKey === 'function') { + transformerCacheKey = await getCacheKey(fileData, filename, { ...options, cacheFS: this._cacheFS, config: this._config, configString, transformerConfig, - }, - ); - } else if (transformer && typeof transformer.getCacheKey === 'function') { - transformerCacheKey = transformer.getCacheKey(fileData, filename, { - ...options, - cacheFS: this._cacheFS, - config: this._config, - configString, - transformerConfig, - }); + }); + } } return this._buildCacheKeyFromFileInfo( @@ -259,7 +250,7 @@ export default class ScriptTransformer { } private async _getTransformerAsync(filename: Config.Path) { - if (!this._config.transform || !this._config.transform.length) { + if (this._config.transform.length === 0) { return null; } @@ -269,12 +260,24 @@ export default class ScriptTransformer { return null; } + if (this._transformCacheMutex.has(transformPath)) { + await this._transformCacheMutex.get(transformPath); + } + const cached = this._transformCache.get(transformPath); if (cached) { return cached; } - let transformer: AsyncTransformer = await import(transformPath); + let importResolve: () => void = () => {}; + this._transformCacheMutex.set( + transformPath, + new Promise(resolve => { + importResolve = resolve; + }), + ); + + let transformer: AsyncTransformer = (await import(transformPath)).default; if (!transformer) { throw new TypeError('Jest: a transform must export something.'); @@ -293,12 +296,13 @@ export default class ScriptTransformer { } const res = {transformer, transformerConfig}; this._transformCache.set(transformPath, res); + importResolve(); return res; } private _getTransformer(filename: Config.Path) { - if (!this._config.transform || !this._config.transform.length) { + if (this._config.transform.length === 0) { return null; } @@ -409,7 +413,7 @@ export default class ScriptTransformer { throw new TypeError( "Jest: a transform's `process` function must return a string, " + 'or an object with `code` key containing this string. ' + - "It's `processAsync` function must return that in a promise.", + "It's `processAsync` function must return a Promise resolving to it.", ); } } @@ -496,7 +500,7 @@ export default class ScriptTransformer { const {transformer, transformerConfig = {}} = this._getTransformer(filename) || {}; const cacheFilePath = this._getFileCachePath(filename, content, options); - const sourceMapPath: Config.Path | null = cacheFilePath + '.map'; + const sourceMapPath: Config.Path = cacheFilePath + '.map'; // Ignore cache if `config.cache` is set (--no-cache) const code = this._config.cache ? readCodeCacheFile(cacheFilePath) : null; @@ -557,7 +561,7 @@ export default class ScriptTransformer { content, options, ); - const sourceMapPath: Config.Path | null = cacheFilePath + '.map'; + const sourceMapPath: Config.Path = cacheFilePath + '.map'; // Ignore cache if `config.cache` is set (--no-cache) const code = this._config.cache ? readCodeCacheFile(cacheFilePath) : null; @@ -860,9 +864,7 @@ export default class ScriptTransformer { const ignoreRegexp = this._cache.ignorePatternsRegExp; const isIgnored = ignoreRegexp ? ignoreRegexp.test(filename) : false; - return ( - !!this._config.transform && !!this._config.transform.length && !isIgnored - ); + return this._config.transform.length !== 0 && !isIgnored; } }