Skip to content

Commit 4ece96b

Browse files
committed
chore(transform): refactor API to pass an options bag around rather than multiple boolean options
1 parent 95169d3 commit 4ece96b

File tree

5 files changed

+55
-82
lines changed

5 files changed

+55
-82
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- `[eslint-config-fb-strict]` Move package from this repo to `fbjs` repo ([#10739](https://github.com/facebook/jest/pull/10739))
2424
- `[examples]` Update TypeScript example to show use of newer Jest types ([#10399](https://github.com/facebook/jest/pull/10399))
2525
- `[jest-cli]` chore: standardize files and folder names ([#10698](https://github.com/facebook/jest/pull/10698))
26+
- `[jest-transform]` [**BREAKING**] Refactor API to pass an options bag around rather than multiple boolean options ([#10753](https://github.com/facebook/jest/pull/10753))
2627

2728
### Performance
2829

packages/jest-reporters/src/generateEmptyCoverage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default function (
7070
const {code} = new ScriptTransformer(config).transformSource(
7171
filename,
7272
source,
73-
true,
73+
{instrument: true},
7474
);
7575
// TODO: consider passing AST
7676
const extracted = readInitialCoverage(code);

packages/jest-transform/src/ScriptTransformer.ts

Lines changed: 44 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {sync as writeFileAtomic} from 'write-file-atomic';
2626
import {addHook} from 'pirates';
2727
import type {
2828
Options,
29+
TransformOptions,
2930
TransformResult,
3031
TransformedSource,
3132
Transformer,
@@ -62,6 +63,14 @@ async function waitForPromiseWithCleanup(
6263
}
6364
}
6465

66+
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/49267
67+
declare module '@babel/core' {
68+
interface TransformCaller {
69+
supportsExportNamespaceFrom?: boolean;
70+
supportsTopLevelAwait?: boolean;
71+
}
72+
}
73+
6574
export default class ScriptTransformer {
6675
private _cache: ProjectCache;
6776
private _config: Config.ProjectConfig;
@@ -93,9 +102,7 @@ export default class ScriptTransformer {
93102
private _getCacheKey(
94103
fileData: string,
95104
filename: Config.Path,
96-
instrument: boolean,
97-
supportsDynamicImport: boolean,
98-
supportsStaticESM: boolean,
105+
options: TransformOptions,
99106
): string {
100107
const configString = this._cache.configString;
101108
const transformer = this._getTransformer(filename);
@@ -105,10 +112,12 @@ export default class ScriptTransformer {
105112
.update(
106113
transformer.getCacheKey(fileData, filename, configString, {
107114
config: this._config,
108-
instrument,
115+
instrument: options.instrument,
109116
rootDir: this._config.rootDir,
110-
supportsDynamicImport,
111-
supportsStaticESM,
117+
supportsDynamicImport: options.supportsDynamicImport,
118+
supportsExportNamespaceFrom: options.supportsExportNamespaceFrom,
119+
supportsStaticESM: options.supportsStaticESM,
120+
supportsTopLevelAwait: options.supportsTopLevelAwait,
112121
}),
113122
)
114123
.update(CACHE_VERSION)
@@ -117,7 +126,7 @@ export default class ScriptTransformer {
117126
return createHash('md5')
118127
.update(fileData)
119128
.update(configString)
120-
.update(instrument ? 'instrument' : '')
129+
.update(options.instrument ? 'instrument' : '')
121130
.update(filename)
122131
.update(CACHE_VERSION)
123132
.digest('hex');
@@ -127,22 +136,14 @@ export default class ScriptTransformer {
127136
private _getFileCachePath(
128137
filename: Config.Path,
129138
content: string,
130-
instrument: boolean,
131-
supportsDynamicImport: boolean,
132-
supportsStaticESM: boolean,
139+
options: TransformOptions,
133140
): Config.Path {
134141
const baseCacheDir = HasteMap.getCacheFilePath(
135142
this._config.cacheDirectory,
136143
'jest-transform-cache-' + this._config.name,
137144
VERSION,
138145
);
139-
const cacheKey = this._getCacheKey(
140-
content,
141-
filename,
142-
instrument,
143-
supportsDynamicImport,
144-
supportsStaticESM,
145-
);
146+
const cacheKey = this._getCacheKey(content, filename, options);
146147
// Create sub folders based on the cacheKey to avoid creating one
147148
// directory with many files.
148149
const cacheDir = path.join(baseCacheDir, cacheKey[0] + cacheKey[1]);
@@ -213,9 +214,8 @@ export default class ScriptTransformer {
213214
private _instrumentFile(
214215
filename: Config.Path,
215216
input: TransformedSource,
216-
supportsDynamicImport: boolean,
217-
supportsStaticESM: boolean,
218217
canMapToInput: boolean,
218+
options: TransformOptions,
219219
): TransformedSource {
220220
const inputCode = typeof input === 'string' ? input : input.code;
221221
const inputMap = typeof input === 'string' ? null : input.map;
@@ -225,8 +225,10 @@ export default class ScriptTransformer {
225225
babelrc: false,
226226
caller: {
227227
name: '@jest/transform',
228-
supportsDynamicImport,
229-
supportsStaticESM,
228+
supportsDynamicImport: options.supportsDynamicImport,
229+
supportsExportNamespaceFrom: options.supportsExportNamespaceFrom,
230+
supportsStaticESM: options.supportsStaticESM,
231+
supportsTopLevelAwait: options.supportsTopLevelAwait,
230232
},
231233
configFile: false,
232234
filename,
@@ -260,23 +262,14 @@ export default class ScriptTransformer {
260262
this._getTransformer(filepath);
261263
}
262264

263-
// TODO: replace third argument with TransformOptions in Jest 26
264265
transformSource(
265266
filepath: Config.Path,
266267
content: string,
267-
instrument: boolean,
268-
supportsDynamicImport = false,
269-
supportsStaticESM = false,
268+
options: TransformOptions,
270269
): TransformResult {
271270
const filename = tryRealpath(filepath);
272271
const transform = this._getTransformer(filename);
273-
const cacheFilePath = this._getFileCachePath(
274-
filename,
275-
content,
276-
instrument,
277-
supportsDynamicImport,
278-
supportsStaticESM,
279-
);
272+
const cacheFilePath = this._getFileCachePath(filename, content, options);
280273
let sourceMapPath: Config.Path | null = cacheFilePath + '.map';
281274
// Ignore cache if `config.cache` is set (--no-cache)
282275
let code = this._config.cache ? readCodeCacheFile(cacheFilePath) : null;
@@ -306,11 +299,12 @@ export default class ScriptTransformer {
306299
};
307300

308301
if (transform && shouldCallTransform) {
309-
const processed = transform.process(content, filename, this._config, {
310-
instrument,
311-
supportsDynamicImport,
312-
supportsStaticESM,
313-
});
302+
const processed = transform.process(
303+
content,
304+
filename,
305+
this._config,
306+
options,
307+
);
314308

315309
if (typeof processed === 'string') {
316310
transformed.code = processed;
@@ -344,7 +338,7 @@ export default class ScriptTransformer {
344338

345339
// Apply instrumentation to the code if necessary, keeping the instrumented code and new map
346340
let map = transformed.map;
347-
if (!transformWillInstrument && instrument) {
341+
if (!transformWillInstrument && options.instrument) {
348342
/**
349343
* We can map the original source code to the instrumented code ONLY if
350344
* - the process of transforming the code produced a source map e.g. ts-jest
@@ -360,9 +354,8 @@ export default class ScriptTransformer {
360354
const instrumented = this._instrumentFile(
361355
filename,
362356
transformed,
363-
supportsDynamicImport,
364-
supportsStaticESM,
365357
shouldEmitSourceMaps,
358+
options,
366359
);
367360

368361
code =
@@ -392,15 +385,10 @@ export default class ScriptTransformer {
392385
private _transformAndBuildScript(
393386
filename: Config.Path,
394387
options: Options,
395-
instrument: boolean,
388+
transformOptions: TransformOptions,
396389
fileSource?: string,
397390
): TransformResult {
398-
const {
399-
isCoreModule,
400-
isInternalModule,
401-
supportsDynamicImport,
402-
supportsStaticESM,
403-
} = options;
391+
const {isCoreModule, isInternalModule} = options;
404392
const content = stripShebang(
405393
fileSource || fs.readFileSync(filename, 'utf8'),
406394
);
@@ -411,16 +399,14 @@ export default class ScriptTransformer {
411399
const willTransform =
412400
!isInternalModule &&
413401
!isCoreModule &&
414-
(this.shouldTransform(filename) || instrument);
402+
(this.shouldTransform(filename) || transformOptions.instrument);
415403

416404
try {
417405
if (willTransform) {
418406
const transformedSource = this.transformSource(
419407
filename,
420408
content,
421-
instrument,
422-
supportsDynamicImport,
423-
supportsStaticESM,
409+
transformOptions,
424410
);
425411

426412
code = transformedSource.code;
@@ -459,7 +445,7 @@ export default class ScriptTransformer {
459445
const result = this._transformAndBuildScript(
460446
filename,
461447
options,
462-
instrument,
448+
{...options, instrument},
463449
fileSource,
464450
);
465451

@@ -475,22 +461,15 @@ export default class ScriptTransformer {
475461
options: Options,
476462
fileSource: string,
477463
): string {
478-
const {
479-
isCoreModule,
480-
isInternalModule,
481-
supportsDynamicImport,
482-
supportsStaticESM,
483-
} = options;
464+
const {isCoreModule, isInternalModule} = options;
484465
const willTransform =
485466
!isInternalModule && !isCoreModule && this.shouldTransform(filename);
486467

487468
if (willTransform) {
488469
const {code: transformedJsonSource} = this.transformSource(
489470
filename,
490471
fileSource,
491-
false,
492-
supportsDynamicImport,
493-
supportsStaticESM,
472+
{...options, instrument: false},
494473
);
495474
return transformedJsonSource;
496475
}
@@ -501,14 +480,17 @@ export default class ScriptTransformer {
501480
requireAndTranspileModule<ModuleType = unknown>(
502481
moduleName: string,
503482
callback?: (module: ModuleType) => void,
483+
transformOptions?: TransformOptions,
504484
): ModuleType;
505485
requireAndTranspileModule<ModuleType = unknown>(
506486
moduleName: string,
507487
callback?: (module: ModuleType) => Promise<void>,
488+
transformOptions?: TransformOptions,
508489
): Promise<ModuleType>;
509490
requireAndTranspileModule<ModuleType = unknown>(
510491
moduleName: string,
511492
callback?: (module: ModuleType) => void | Promise<void>,
493+
transformOptions: TransformOptions = {instrument: false},
512494
): ModuleType | Promise<ModuleType> {
513495
// Load the transformer to avoid a cycle where we need to load a
514496
// transformer in order to transform it in the require hooks
@@ -520,9 +502,7 @@ export default class ScriptTransformer {
520502
try {
521503
transforming = true;
522504
return (
523-
// we might wanna do `supportsDynamicImport` at some point
524-
this.transformSource(filename, code, false, false, false).code ||
525-
code
505+
this.transformSource(filename, code, transformOptions).code || code
526506
);
527507
} finally {
528508
transforming = false;

packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ Object {
7070
},
7171
"instrument": true,
7272
"rootDir": "/",
73-
"supportsDynamicImport": false,
74-
"supportsStaticESM": false,
73+
"supportsDynamicImport": undefined,
74+
"supportsExportNamespaceFrom": undefined,
75+
"supportsStaticESM": undefined,
76+
"supportsTopLevelAwait": undefined,
7577
}
7678
`;
7779

packages/jest-transform/src/__tests__/script_transformer.test.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,7 @@ describe('ScriptTransformer', () => {
473473

474474
const result = scriptTransformer.transform(
475475
'/fruits/banana.js',
476-
makeGlobalConfig({
477-
collectCoverage: true,
478-
}),
476+
makeGlobalConfig({collectCoverage: true}),
479477
);
480478
expect(result.sourceMapPath).toBeNull();
481479
expect(writeFileAtomic.sync).toBeCalledTimes(1);
@@ -532,9 +530,7 @@ describe('ScriptTransformer', () => {
532530

533531
const result = scriptTransformer.transform(
534532
'/fruits/banana.js',
535-
makeGlobalConfig({
536-
collectCoverage: true,
537-
}),
533+
makeGlobalConfig({collectCoverage: true}),
538534
);
539535
expect(result.sourceMapPath).toBeFalsy();
540536
expect(writeFileAtomic.sync).toHaveBeenCalledTimes(1);
@@ -571,9 +567,7 @@ describe('ScriptTransformer', () => {
571567

572568
const result = scriptTransformer.transform(
573569
'/fruits/banana.js',
574-
makeGlobalConfig({
575-
collectCoverage: true,
576-
}),
570+
makeGlobalConfig({collectCoverage: true}),
577571
);
578572
expect(result.sourceMapPath).toEqual(expect.any(String));
579573
expect(writeFileAtomic.sync).toBeCalledTimes(2);
@@ -609,9 +603,7 @@ describe('ScriptTransformer', () => {
609603

610604
const result = scriptTransformer.transform(
611605
'/fruits/banana.js',
612-
makeGlobalConfig({
613-
collectCoverage: true,
614-
}),
606+
makeGlobalConfig({collectCoverage: true}),
615607
);
616608
expect(result.sourceMapPath).toEqual(expect.any(String));
617609
expect(writeFileAtomic.sync).toBeCalledTimes(2);
@@ -631,9 +623,7 @@ describe('ScriptTransformer', () => {
631623

632624
scriptTransformer.transform(
633625
'/fruits/banana.js',
634-
makeGlobalConfig({
635-
collectCoverage: true,
636-
}),
626+
makeGlobalConfig({collectCoverage: true}),
637627
);
638628

639629
const {getCacheKey} = require('test_preprocessor');

0 commit comments

Comments
 (0)