From edf8c0a28d247d7e262b4d030b5a92aff90bb304 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sun, 5 Apr 2020 12:15:16 +0200 Subject: [PATCH] feat: pass ESM options to transformers (#9597) --- CHANGELOG.md | 1 + packages/jest-runtime/src/index.ts | 16 +++- .../jest-transform/src/ScriptTransformer.ts | 76 +++++++++++++++---- 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6be6ed5729f1..8946e97c57a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - `[babel-jest]` Support passing `supportsDynamicImport` and `supportsStaticESM` ([#9766](https://github.com/facebook/jest/pull/9766)) +- `[jest-runtime, @jest/transformer]` Support passing `supportsDynamicImport` and `supportsStaticESM` ([#9597](https://github.com/facebook/jest/pull/9597)) ### Fixes diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 55c06ff81ad2..3566ac18cafa 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -52,6 +52,14 @@ type HasteMapOptions = { type InternalModuleOptions = { isInternalModule: boolean; + supportsDynamicImport: boolean; + supportsStaticESM: boolean; +}; + +const defaultTransformOptions: InternalModuleOptions = { + isInternalModule: false, + supportsDynamicImport: false, + supportsStaticESM: false, }; type InitialModule = Partial & @@ -368,7 +376,11 @@ class Runtime { } requireInternalModule(from: Config.Path, to?: string): T { - return this.requireModule(from, to, {isInternalModule: true}); + return this.requireModule(from, to, { + isInternalModule: true, + supportsDynamicImport: false, + supportsStaticESM: false, + }); } requireActual(from: Config.Path, moduleName: string): T { @@ -493,7 +505,7 @@ class Runtime { } private _getFullTransformationOptions( - options: InternalModuleOptions | undefined, + options: InternalModuleOptions = defaultTransformOptions, ): TransformationOptions { return { ...options, diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 3e595580436e..1ad4109cd83a 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -90,6 +90,8 @@ export default class ScriptTransformer { fileData: string, filename: Config.Path, instrument: boolean, + supportsDynamicImport: boolean, + supportsStaticESM: boolean, ): string { const configString = this._cache.configString; const transformer = this._getTransformer(filename); @@ -101,8 +103,8 @@ export default class ScriptTransformer { config: this._config, instrument, rootDir: this._config.rootDir, - supportsDynamicImport: false, - supportsStaticESM: false, + supportsDynamicImport, + supportsStaticESM, }), ) .update(CACHE_VERSION) @@ -122,13 +124,21 @@ export default class ScriptTransformer { filename: Config.Path, content: string, instrument: boolean, + supportsDynamicImport: boolean, + supportsStaticESM: boolean, ): Config.Path { const baseCacheDir = HasteMap.getCacheFilePath( this._config.cacheDirectory, 'jest-transform-cache-' + this._config.name, VERSION, ); - const cacheKey = this._getCacheKey(content, filename, instrument); + const cacheKey = this._getCacheKey( + content, + filename, + instrument, + supportsDynamicImport, + supportsStaticESM, + ); // Create sub folders based on the cacheKey to avoid creating one // directory with many files. const cacheDir = path.join(baseCacheDir, cacheKey[0] + cacheKey[1]); @@ -193,13 +203,19 @@ export default class ScriptTransformer { return transform; } - private _instrumentFile(filename: Config.Path, content: string): string { + private _instrumentFile( + filename: Config.Path, + content: string, + supportsDynamicImport: boolean, + supportsStaticESM: boolean, + ): string { const result = babelTransform(content, { auxiliaryCommentBefore: ' istanbul ignore next ', babelrc: false, caller: { name: '@jest/transform', - supportsStaticESM: false, + supportsDynamicImport, + supportsStaticESM, }, configFile: false, filename, @@ -243,14 +259,23 @@ export default class ScriptTransformer { this._getTransformer(filepath); } + // TODO: replace third argument with TransformOptions in Jest 26 transformSource( filepath: Config.Path, content: string, instrument: boolean, + supportsDynamicImport = false, + supportsStaticESM = false, ): TransformResult { const filename = this._getRealPath(filepath); const transform = this._getTransformer(filename); - const cacheFilePath = this._getFileCachePath(filename, content, instrument); + const cacheFilePath = this._getFileCachePath( + filename, + content, + instrument, + supportsDynamicImport, + supportsStaticESM, + ); let sourceMapPath: Config.Path | null = cacheFilePath + '.map'; // Ignore cache if `config.cache` is set (--no-cache) let code = this._config.cache ? readCodeCacheFile(cacheFilePath) : null; @@ -287,8 +312,8 @@ export default class ScriptTransformer { if (transform && shouldCallTransform) { const processed = transform.process(content, filename, this._config, { instrument, - supportsDynamicImport: false, - supportsStaticESM: false, + supportsDynamicImport, + supportsStaticESM, }); if (typeof processed === 'string') { @@ -323,7 +348,12 @@ export default class ScriptTransformer { } if (!transformWillInstrument && instrument) { - code = this._instrumentFile(filename, transformed.code); + code = this._instrumentFile( + filename, + transformed.code, + supportsDynamicImport, + supportsStaticESM, + ); } else { code = transformed.code; } @@ -350,12 +380,16 @@ export default class ScriptTransformer { private _transformAndBuildScript( filename: Config.Path, - options: Options | null, + options: Options, instrument: boolean, fileSource?: string, ): TransformResult { - const isInternalModule = !!(options && options.isInternalModule); - const isCoreModule = !!(options && options.isCoreModule); + const { + isCoreModule, + isInternalModule, + supportsDynamicImport, + supportsStaticESM, + } = options; const content = stripShebang( fileSource || fs.readFileSync(filename, 'utf8'), ); @@ -375,6 +409,8 @@ export default class ScriptTransformer { filename, content, instrument, + supportsDynamicImport, + supportsStaticESM, ); code = transformedSource.code; @@ -431,8 +467,12 @@ export default class ScriptTransformer { options: Options, fileSource: string, ): string { - const isInternalModule = options.isInternalModule; - const isCoreModule = options.isCoreModule; + const { + isCoreModule, + isInternalModule, + supportsDynamicImport, + supportsStaticESM, + } = options; const willTransform = !isInternalModule && !isCoreModule && this.shouldTransform(filename); @@ -441,6 +481,8 @@ export default class ScriptTransformer { filename, fileSource, false, + supportsDynamicImport, + supportsStaticESM, ); return transformedJsonSource; } @@ -469,7 +511,11 @@ export default class ScriptTransformer { (code, filename) => { try { transforming = true; - return this.transformSource(filename, code, false).code || code; + return ( + // we might wanna do `supportsDynamicImport` at some point + this.transformSource(filename, code, false, false, false).code || + code + ); } finally { transforming = false; }