Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: migrate @jest/transform to TypeScript #7918

Merged
merged 4 commits into from Feb 17, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -43,6 +43,7 @@
- `[@jest/transform]`: New package extracted from `jest-runtime` ([#7915](https://github.com/facebook/jest/pull/7915))
- `[babel-plugin-jest-hoist]`: Migrate to TypeScript ([#7898](https://github.com/facebook/jest/pull/7898))
- `[@jest/core]` Create new package, which is `jest-cli` minus `yargs` and `prompts` ([#7696](https://github.com/facebook/jest/pull/7696))
- `[@jest/transform]`: Migrate to TypeScript ([#7918](https://github.com/facebook/jest/pull/7918))

### Performance

Expand Down
3 changes: 2 additions & 1 deletion packages/babel-jest/package.json
Expand Up @@ -11,15 +11,16 @@
"main": "build/index.js",
"types": "build/index.d.ts",
"dependencies": {
"@jest/transform": "^24.1.0",
"@jest/types": "^24.1.0",
"@types/babel__core": "^7.0.4",
"babel-plugin-istanbul": "^5.1.0",
"babel-preset-jest": "^24.1.0",
"chalk": "^2.4.2",
"slash": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.1.0",
"@types/babel__core": "^7.0.4",
"@types/slash": "^2.0.0"
},
"peerDependencies": {
Expand Down
6 changes: 2 additions & 4 deletions packages/babel-jest/src/__tests__/index.ts
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import {Config, Transform} from '@jest/types';
import {Config} from '@jest/types';
import babelJest from '../index';

//Mock data for all the tests
Expand All @@ -30,14 +30,12 @@ test(`Returns source string with inline maps when no transformOptions is passed`
sourceString,
'dummy_path.js',
(mockConfig as unknown) as Config.ProjectConfig,
) as Transform.TransformedSource;
) as any;
expect(typeof result).toBe('object');
expect(result.code).toBeDefined();
expect(result.map).toBeDefined();
expect(result.code).toMatch('//# sourceMappingURL');
expect(result.code).toMatch('customMultiply');
// @ts-ignore: it's fine if we get wrong types, the tests will fail then
expect(result.map.sources).toEqual(['dummy_path.js']);
// @ts-ignore: it's fine if we get wrong types, the tests will fail then
expect(JSON.stringify(result.map.sourcesContent)).toMatch('customMultiply');
});
52 changes: 23 additions & 29 deletions packages/babel-jest/src/index.ts
Expand Up @@ -8,12 +8,13 @@
import crypto from 'crypto';
import fs from 'fs';
import path from 'path';
import {Config, Transform} from '@jest/types';
import {Transformer} from '@jest/transform';
import {Config} from '@jest/types';
import {
transformSync as babelTransform,
loadPartialConfig,
TransformOptions,
PartialConfig,
TransformOptions,
transformSync as babelTransform,
} from '@babel/core';
import chalk from 'chalk';
import slash from 'slash';
Expand All @@ -22,12 +23,18 @@ const THIS_FILE = fs.readFileSync(__filename);
const jestPresetPath = require.resolve('babel-preset-jest');
const babelIstanbulPlugin = require.resolve('babel-plugin-istanbul');

// Narrow down the types
Copy link
Member Author

@SimenB SimenB Feb 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quite happy with how this turned out. By using an interface, we can narrow down the type, and it'll tell us here if we break Transform's contract, and not just a local one. It also narrows down options of the factory to babel's options instead of any

And importers of babel-jest directly will see that createTransformer is always there - it's not possibly undefined. Pretty nice!

interface BabelJestTransformer extends Transformer {
canInstrument: true;
createTransformer: (options?: TransformOptions) => BabelJestTransformer;
}

const createTransformer = (
options: TransformOptions = {},
): Transform.Transformer => {
): BabelJestTransformer => {
options = {
...options,
// @ts-ignore: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32955
// @ts-ignore: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/33118
caller: {
name: 'babel-jest',
supportsStaticESM: false,
Expand Down Expand Up @@ -58,18 +65,15 @@ const createTransformer = (
return babelConfig;
}

return {
const transformer: BabelJestTransformer = {
Copy link
Member Author

@SimenB SimenB Feb 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setting the type here allows us to not type all of the args explicitly

canInstrument: true,
createTransformer,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was the solution to the FIXME below 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This broke all usages of createTransformer (vs using the transformer that's already created by Jest) because the object createTransformer returns also has a createTransformer property, which is checked in @babel/transform to use that instead of the passed one: https://github.com/facebook/jest/blob/master/packages/jest-transform/src/ScriptTransformer.ts#L157

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, oops! 😛 Good catch!

getCacheKey(
fileData: string,
filename: Config.Path,
configString: string,
{
config,
instrument,
rootDir,
}: {config: Config.ProjectConfig} & Transform.CacheKeyOptions,
): string {
fileData,
filename,
configString,
{config, instrument, rootDir},
) {
const babelOptions = loadBabelConfig(config.cwd, filename);
const configPath = [
babelOptions.config || '',
Expand Down Expand Up @@ -97,12 +101,7 @@ const createTransformer = (
.update(process.env.BABEL_ENV || '')
.digest('hex');
},
process(
src: string,
filename: Config.Path,
config: Config.ProjectConfig,
transformOptions?: Transform.TransformOptions,
): string | Transform.TransformedSource {
process(src, filename, config, transformOptions) {
const babelOptions = {...loadBabelConfig(config.cwd, filename).options};

if (transformOptions && transformOptions.instrument) {
Expand Down Expand Up @@ -132,13 +131,8 @@ const createTransformer = (
return src;
},
};
};

const transformer = createTransformer();

// FIXME: This is not part of the exported TS types. When fixed, remember to
// move @types/babel__core to `dependencies` instead of `devDependencies`
// (one fix is to use ESM, maybe for Jest 25?)
transformer.createTransformer = createTransformer;
return transformer;
};

export = transformer;
export = createTransformer();
1 change: 1 addition & 0 deletions packages/babel-jest/tsconfig.json
Expand Up @@ -6,6 +6,7 @@
},
// TODO: include `babel-preset-jest` if it's ever in TS even though we don't care about its types
"references": [
{"path": "../jest-transform"},
{"path": "../jest-types"}
]
}
3 changes: 3 additions & 0 deletions packages/jest-transform/package.json
Expand Up @@ -10,6 +10,7 @@
"main": "build/index.js",
"dependencies": {
"@babel/core": "^7.1.0",
"@jest/types": "^24.1.0",
"babel-plugin-istanbul": "^5.1.0",
"chalk": "^2.0.1",
"convert-source-map": "^1.4.0",
Expand All @@ -21,11 +22,13 @@
"micromatch": "^3.1.10",
"realpath-native": "^1.1.0",
"slash": "^2.0.0",
"source-map": "^0.6.1",
"write-file-atomic": "2.4.1"
},
"devDependencies": {
"@types/babel__core": "^7.0.4",
"@types/convert-source-map": "^1.5.1",
"@types/fast-json-stable-stringify": "^2.0.0",
"@types/graceful-fs": "^4.1.2",
"@types/micromatch": "^3.1.0",
"@types/write-file-atomic": "^2.1.1"
Expand Down