Skip to content

Commit 3db82bc

Browse files
committed
chore(transform): refactor API to pass an options bag around rather than multiple boolean options
1 parent 2b748f6 commit 3db82bc

File tree

4 files changed

+51
-68
lines changed

4 files changed

+51
-68
lines changed

CHANGELOG.md

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

2829
### Performance
2930

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: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import handlePotentialSyntaxError from './enhanceUnexpectedTokenMessage';
2828
import shouldInstrument from './shouldInstrument';
2929
import type {
3030
Options,
31+
TransformOptions,
3132
TransformResult,
3233
TransformedSource,
3334
Transformer,
@@ -61,6 +62,14 @@ async function waitForPromiseWithCleanup(
6162
}
6263
}
6364

65+
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/49267
66+
declare module '@babel/core' {
67+
interface TransformCaller {
68+
supportsExportNamespaceFrom?: boolean;
69+
supportsTopLevelAwait?: boolean;
70+
}
71+
}
72+
6473
export default class ScriptTransformer {
6574
private _cache: ProjectCache;
6675
private _config: Config.ProjectConfig;
@@ -92,9 +101,7 @@ export default class ScriptTransformer {
92101
private _getCacheKey(
93102
fileData: string,
94103
filename: Config.Path,
95-
instrument: boolean,
96-
supportsDynamicImport: boolean,
97-
supportsStaticESM: boolean,
104+
options: TransformOptions,
98105
): string {
99106
const configString = this._cache.configString;
100107
const transformer = this._getTransformer(filename);
@@ -104,10 +111,12 @@ export default class ScriptTransformer {
104111
.update(
105112
transformer.getCacheKey(fileData, filename, configString, {
106113
config: this._config,
107-
instrument,
114+
instrument: options.instrument,
108115
rootDir: this._config.rootDir,
109-
supportsDynamicImport,
110-
supportsStaticESM,
116+
supportsDynamicImport: options.supportsDynamicImport,
117+
supportsExportNamespaceFrom: options.supportsExportNamespaceFrom,
118+
supportsStaticESM: options.supportsStaticESM,
119+
supportsTopLevelAwait: options.supportsTopLevelAwait,
111120
}),
112121
)
113122
.update(CACHE_VERSION)
@@ -116,7 +125,7 @@ export default class ScriptTransformer {
116125
return createHash('md5')
117126
.update(fileData)
118127
.update(configString)
119-
.update(instrument ? 'instrument' : '')
128+
.update(options.instrument ? 'instrument' : '')
120129
.update(filename)
121130
.update(CACHE_VERSION)
122131
.digest('hex');
@@ -126,22 +135,14 @@ export default class ScriptTransformer {
126135
private _getFileCachePath(
127136
filename: Config.Path,
128137
content: string,
129-
instrument: boolean,
130-
supportsDynamicImport: boolean,
131-
supportsStaticESM: boolean,
138+
options: TransformOptions,
132139
): Config.Path {
133140
const baseCacheDir = HasteMap.getCacheFilePath(
134141
this._config.cacheDirectory,
135142
'jest-transform-cache-' + this._config.name,
136143
VERSION,
137144
);
138-
const cacheKey = this._getCacheKey(
139-
content,
140-
filename,
141-
instrument,
142-
supportsDynamicImport,
143-
supportsStaticESM,
144-
);
145+
const cacheKey = this._getCacheKey(content, filename, options);
145146
// Create sub folders based on the cacheKey to avoid creating one
146147
// directory with many files.
147148
const cacheDir = path.join(baseCacheDir, cacheKey[0] + cacheKey[1]);
@@ -212,9 +213,8 @@ export default class ScriptTransformer {
212213
private _instrumentFile(
213214
filename: Config.Path,
214215
input: TransformedSource,
215-
supportsDynamicImport: boolean,
216-
supportsStaticESM: boolean,
217216
canMapToInput: boolean,
217+
options: TransformOptions,
218218
): TransformedSource {
219219
const inputCode = typeof input === 'string' ? input : input.code;
220220
const inputMap = typeof input === 'string' ? null : input.map;
@@ -224,8 +224,10 @@ export default class ScriptTransformer {
224224
babelrc: false,
225225
caller: {
226226
name: '@jest/transform',
227-
supportsDynamicImport,
228-
supportsStaticESM,
227+
supportsDynamicImport: options.supportsDynamicImport,
228+
supportsExportNamespaceFrom: options.supportsExportNamespaceFrom,
229+
supportsStaticESM: options.supportsStaticESM,
230+
supportsTopLevelAwait: options.supportsTopLevelAwait,
229231
},
230232
configFile: false,
231233
filename,
@@ -259,23 +261,14 @@ export default class ScriptTransformer {
259261
this._getTransformer(filepath);
260262
}
261263

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

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

314308
if (typeof processed === 'string') {
315309
transformed.code = processed;
@@ -343,7 +337,7 @@ export default class ScriptTransformer {
343337

344338
// Apply instrumentation to the code if necessary, keeping the instrumented code and new map
345339
let map = transformed.map;
346-
if (!transformWillInstrument && instrument) {
340+
if (!transformWillInstrument && options.instrument) {
347341
/**
348342
* We can map the original source code to the instrumented code ONLY if
349343
* - the process of transforming the code produced a source map e.g. ts-jest
@@ -359,9 +353,8 @@ export default class ScriptTransformer {
359353
const instrumented = this._instrumentFile(
360354
filename,
361355
transformed,
362-
supportsDynamicImport,
363-
supportsStaticESM,
364356
shouldEmitSourceMaps,
357+
options,
365358
);
366359

367360
code =
@@ -391,15 +384,10 @@ export default class ScriptTransformer {
391384
private _transformAndBuildScript(
392385
filename: Config.Path,
393386
options: Options,
394-
instrument: boolean,
387+
transformOptions: TransformOptions,
395388
fileSource?: string,
396389
): TransformResult {
397-
const {
398-
isCoreModule,
399-
isInternalModule,
400-
supportsDynamicImport,
401-
supportsStaticESM,
402-
} = options;
390+
const {isCoreModule, isInternalModule} = options;
403391
const content = stripShebang(
404392
fileSource || fs.readFileSync(filename, 'utf8'),
405393
);
@@ -410,16 +398,14 @@ export default class ScriptTransformer {
410398
const willTransform =
411399
!isInternalModule &&
412400
!isCoreModule &&
413-
(this.shouldTransform(filename) || instrument);
401+
(this.shouldTransform(filename) || transformOptions.instrument);
414402

415403
try {
416404
if (willTransform) {
417405
const transformedSource = this.transformSource(
418406
filename,
419407
content,
420-
instrument,
421-
supportsDynamicImport,
422-
supportsStaticESM,
408+
transformOptions,
423409
);
424410

425411
code = transformedSource.code;
@@ -439,7 +425,7 @@ export default class ScriptTransformer {
439425
transform(
440426
filename: Config.Path,
441427
options: Options,
442-
fileSource?: string,
428+
fileSource: string,
443429
): TransformResult {
444430
let scriptCacheKey = undefined;
445431
let instrument = false;
@@ -458,7 +444,7 @@ export default class ScriptTransformer {
458444
const result = this._transformAndBuildScript(
459445
filename,
460446
options,
461-
instrument,
447+
{...options, instrument},
462448
fileSource,
463449
);
464450

@@ -474,22 +460,15 @@ export default class ScriptTransformer {
474460
options: Options,
475461
fileSource: string,
476462
): string {
477-
const {
478-
isCoreModule,
479-
isInternalModule,
480-
supportsDynamicImport,
481-
supportsStaticESM,
482-
} = options;
463+
const {isCoreModule, isInternalModule} = options;
483464
const willTransform =
484465
!isInternalModule && !isCoreModule && this.shouldTransform(filename);
485466

486467
if (willTransform) {
487468
const {code: transformedJsonSource} = this.transformSource(
488469
filename,
489470
fileSource,
490-
false,
491-
supportsDynamicImport,
492-
supportsStaticESM,
471+
{...options, instrument: false},
493472
);
494473
return transformedJsonSource;
495474
}
@@ -500,14 +479,17 @@ export default class ScriptTransformer {
500479
requireAndTranspileModule<ModuleType = unknown>(
501480
moduleName: string,
502481
callback?: (module: ModuleType) => void,
482+
transformOptions?: TransformOptions,
503483
): ModuleType;
504484
requireAndTranspileModule<ModuleType = unknown>(
505485
moduleName: string,
506486
callback?: (module: ModuleType) => Promise<void>,
487+
transformOptions?: TransformOptions,
507488
): Promise<ModuleType>;
508489
requireAndTranspileModule<ModuleType = unknown>(
509490
moduleName: string,
510491
callback?: (module: ModuleType) => void | Promise<void>,
492+
transformOptions: TransformOptions = {instrument: false},
511493
): ModuleType | Promise<ModuleType> {
512494
// Load the transformer to avoid a cycle where we need to load a
513495
// transformer in order to transform it in the require hooks
@@ -519,9 +501,7 @@ export default class ScriptTransformer {
519501
try {
520502
transforming = true;
521503
return (
522-
// we might wanna do `supportsDynamicImport` at some point
523-
this.transformSource(filename, code, false, false, false).code ||
524-
code
504+
this.transformSource(filename, code, transformOptions).code || code
525505
);
526506
} finally {
527507
transforming = false;

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

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

0 commit comments

Comments
 (0)