Skip to content

Commit

Permalink
feat: create new @jest/transform package
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Feb 16, 2019
1 parent e760ec4 commit 958affe
Show file tree
Hide file tree
Showing 19 changed files with 127 additions and 56 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -40,6 +40,7 @@
- `[jest-resolve]`: Migrate to TypeScript ([#7871](https://github.com/facebook/jest/pull/7871))
- `[@jest/reporter]`: New package extracted from `jest-cli` ([#7902](https://github.com/facebook/jest/pull/7902))
- `[jest-snapshot]`: Migrate to TypeScript ([#7899](https://github.com/facebook/jest/pull/7899))
- `[@jest/transform]`: New package extracted from `jest-runtime`

### Performance

Expand Down
1 change: 1 addition & 0 deletions packages/jest-cli/package.json
Expand Up @@ -5,6 +5,7 @@
"main": "build/jest.js",
"dependencies": {
"@jest/reporters": "^24.1.0",
"@jest/transform": "^24.1.0",
"ansi-escapes": "^3.0.0",
"chalk": "^2.0.1",
"exit": "^0.1.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-cli/src/runGlobalHook.js
Expand Up @@ -13,7 +13,7 @@ import type {Test} from 'types/TestRunner';
import {extname} from 'path';
import pEachSeries from 'p-each-series';
import {addHook} from 'pirates';
import Runtime from 'jest-runtime';
import {ScriptTransformer} from '@jest/transform';

// copied from https://github.com/babel/babel/blob/56044c7851d583d498f919e9546caddf8f80a72f/packages/babel-helpers/src/helpers.js#L558-L562
function _interopRequireDefault(obj) {
Expand Down Expand Up @@ -52,7 +52,7 @@ export default ({
: // Fallback to first config
allTests[0].context.config;

const transformer = new Runtime.ScriptTransformer(projectConfig);
const transformer = new ScriptTransformer(projectConfig);

// Load the transformer to avoid a cycle where we need to load a
// transformer in order to transform it in the require hooks
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-reporters/package.json
Expand Up @@ -4,10 +4,10 @@
"version": "24.1.0",
"main": "build/index.js",
"dependencies": {
"@jest/transform": "^24.1.0",
"chalk": "^2.0.1",
"exit": "^0.1.2",
"glob": "^7.1.2",
"jest-runtime": "^24.1.0",
"istanbul-api": "^2.1.1",
"istanbul-lib-coverage": "^2.0.2",
"istanbul-lib-instrument": "^3.0.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-reporters/src/generateEmptyCoverage.js
Expand Up @@ -11,7 +11,7 @@ import type {GlobalConfig, ProjectConfig, Path} from 'types/Config';

import {readInitialCoverage} from 'istanbul-lib-instrument';
import {classes} from 'istanbul-lib-coverage';
import Runtime from 'jest-runtime';
import {shouldInstrument, ScriptTransformer} from '@jest/transform';

export type CoverageWorkerResult = {|
coverage: any,
Expand All @@ -33,9 +33,9 @@ export default function(
collectCoverageFrom: globalConfig.collectCoverageFrom,
collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom,
};
if (Runtime.shouldInstrument(filename, coverageOptions, config)) {
if (shouldInstrument(filename, coverageOptions, config)) {
// Transform file with instrumentation to make sure initial coverage data is well mapped to original code.
const {code, mapCoverage, sourceMapPath} = new Runtime.ScriptTransformer(
const {code, mapCoverage, sourceMapPath} = new ScriptTransformer(
config,
).transformSource(filename, source, true);
const extracted = readInitialCoverage(code);
Expand Down
1 change: 1 addition & 0 deletions packages/jest-runtime/package.json
Expand Up @@ -10,6 +10,7 @@
"main": "build/index.js",
"dependencies": {
"@babel/core": "^7.1.0",
"@jest/transform": "^24.1.0",
"babel-plugin-istanbul": "^5.1.0",
"chalk": "^2.0.1",
"convert-source-map": "^1.4.0",
Expand Down
Expand Up @@ -11,7 +11,7 @@
import vm from 'vm';
import path from 'path';
import os from 'os';
import ScriptTransformer from '../ScriptTransformer';
import {ScriptTransformer} from '@jest/transform';

jest.mock('vm');

Expand Down
32 changes: 0 additions & 32 deletions packages/jest-runtime/src/helpers.js
Expand Up @@ -5,41 +5,9 @@
import type {Path} from 'types/Config';

import path from 'path';
import chalk from 'chalk';
import slash from 'slash';
import glob from 'glob';

const DOT = ' \u2022 ';

export const enhanceUnexpectedTokenMessage = (e: Error) => {
e.stack =
`${chalk.bold.red('Jest encountered an unexpected token')}
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
${DOT}To have some of your "node_modules" files transformed, you can specify a custom ${chalk.bold(
'"transformIgnorePatterns"',
)} in your config.
${DOT}If you need a custom transformation specify a ${chalk.bold(
'"transform"',
)} option in your config.
${DOT}If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the ${chalk.bold(
'"moduleNameMapper"',
)} config option.
You'll find more details and examples of these config options in the docs:
${chalk.cyan('https://jestjs.io/docs/en/configuration.html')}
${chalk.bold.red('Details:')}
` + e.stack;

return e;
};

export const findSiblingsWithFileExtension = (
moduleFileExtensions: Array<string>,
from: Path,
Expand Down
3 changes: 1 addition & 2 deletions packages/jest-runtime/src/index.js
Expand Up @@ -24,10 +24,9 @@ import Resolver from 'jest-resolve';
import {createDirectory, deepCyclicCopy} from 'jest-util';
import {escapePathForRegex} from 'jest-regex-util';
import Snapshot from 'jest-snapshot';
import {ScriptTransformer, shouldInstrument} from '@jest/transform';
import fs from 'graceful-fs';
import stripBOM from 'strip-bom';
import ScriptTransformer from './ScriptTransformer';
import shouldInstrument from './shouldInstrument';
import {run as cliRun} from './cli';
import {options as cliOptions} from './cli/args';
import {findSiblingsWithFileExtension} from './helpers';
Expand Down
3 changes: 3 additions & 0 deletions packages/jest-transform/.npmignore
@@ -0,0 +1,3 @@
**/__mocks__/**
**/__tests__/**
src
38 changes: 38 additions & 0 deletions packages/jest-transform/package.json
@@ -0,0 +1,38 @@
{
"name": "@jest/transform",
"version": "24.1.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/jest.git",
"directory": "packages/jest-transform"
},
"license": "MIT",
"main": "build/index.js",
"dependencies": {
"@babel/core": "^7.1.0",
"babel-plugin-istanbul": "^5.1.0",
"chalk": "^2.0.1",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
"graceful-fs": "^4.1.15",
"jest-haste-map": "^24.0.0",
"jest-regex-util": "^24.0.0",
"jest-util": "^24.0.0",
"micromatch": "^3.1.10",
"realpath-native": "^1.1.0",
"slash": "^2.0.0",
"write-file-atomic": "2.4.1"
},
"devDependencies": {
"@types/babel__core": "^7.0.4",
"@types/convert-source-map": "^1.5.1",
"@types/graceful-fs": "^4.1.2",
"@types/micromatch": "^3.1.0",
"@types/write-file-atomic": "^2.1.1",
"jest-config": "^24.1.0"
},
"engines": {
"node": ">= 6"
},
"gitHead": "b16789230fd45056a7f2fa199bae06c7a1780deb"
}
Expand Up @@ -7,21 +7,21 @@
* @flow
*/

import type {Glob, Path, ProjectConfig} from 'types/Config';
import type {Path, ProjectConfig} from 'types/Config';
import type {
Transformer,
TransformedSource,
TransformResult,
} from 'types/Transform';
import type {ErrorWithCode} from 'types/Errors';
import type {Options} from './types';

import crypto from 'crypto';
import path from 'path';
import vm from 'vm';
import {createDirectory} from 'jest-util';
import fs from 'graceful-fs';
import {transformSync as babelTransform} from '@babel/core';
import babelPluginIstanbul from 'babel-plugin-istanbul';
import convertSourceMap from 'convert-source-map';
import HasteMap from 'jest-haste-map';
import stableStringify from 'fast-json-stable-stringify';
Expand All @@ -30,24 +30,16 @@ import {version as VERSION} from '../package.json';
import shouldInstrument from './shouldInstrument';
import writeFileAtomic from 'write-file-atomic';
import {sync as realpath} from 'realpath-native';
import {enhanceUnexpectedTokenMessage} from './helpers';

export type Options = {|
changedFiles: ?Set<Path>,
collectCoverage: boolean,
collectCoverageFrom: Array<Glob>,
collectCoverageOnlyFrom: ?{[key: string]: boolean, __proto__: null},
extraGlobals?: Array<string>,
isCoreModule?: boolean,
isInternalModule?: boolean,
|};
import enhanceUnexpectedTokenMessage from './enhanceUnexpectedTokenMessage';

type ProjectCache = {|
configString: string,
ignorePatternsRegExp: ?RegExp,
transformedFiles: Map<string, TransformResult>,
|};

const babelPluginIstanbul = require.resolve('babel-plugin-istanbul');

// This data structure is used to avoid recalculating some data every time that
// we need to transform a file. Since ScriptTransformer is instantiated for each
// file we need to keep this object in the local scope of this module.
Expand Down Expand Up @@ -175,7 +167,7 @@ export default class ScriptTransformer {
auxiliaryCommentBefore: ' istanbul ignore next ',
babelrc: false,
caller: {
name: 'jest-runtime',
name: '@jest/transform',
supportsStaticESM: false,
},
configFile: false,
Expand Down
36 changes: 36 additions & 0 deletions packages/jest-transform/src/enhanceUnexpectedTokenMessage.js
@@ -0,0 +1,36 @@
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.

// @flow

import chalk from 'chalk';

const DOT = ' \u2022 ';

export default function enhanceUnexpectedTokenMessage(e: Error) {
e.stack =
`${chalk.bold.red('Jest encountered an unexpected token')}
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
${DOT}To have some of your "node_modules" files transformed, you can specify a custom ${chalk.bold(
'"transformIgnorePatterns"',
)} in your config.
${DOT}If you need a custom transformation specify a ${chalk.bold(
'"transform"',
)} option in your config.
${DOT}If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the ${chalk.bold(
'"moduleNameMapper"',
)} config option.
You'll find more details and examples of these config options in the docs:
${chalk.cyan('https://jestjs.io/docs/en/configuration.html')}
${chalk.bold.red('Details:')}
` + e.stack;

return e;
}
11 changes: 11 additions & 0 deletions packages/jest-transform/src/index.js
@@ -0,0 +1,11 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export {default as ScriptTransformer} from './ScriptTransformer';
export {default as shouldInstrument} from './shouldInstrument';
Expand Up @@ -8,7 +8,7 @@
*/

import type {Path, ProjectConfig} from 'types/Config';
import type {Options} from './ScriptTransformer';
import type {Options} from './types';

import path from 'path';
import {escapePathForRegex} from 'jest-regex-util';
Expand Down
21 changes: 21 additions & 0 deletions packages/jest-transform/src/types.js
@@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {Glob, Path} from 'types/Config';

// TODO: Pick from `GlobalConfig`
export type Options = {|
changedFiles: ?Set<Path>,
collectCoverage: boolean,
collectCoverageFrom: Array<Glob>,
collectCoverageOnlyFrom: ?{[key: string]: boolean, __proto__: null},
extraGlobals?: Array<string>,
isCoreModule?: boolean,
isInternalModule?: boolean,
|};

0 comments on commit 958affe

Please sign in to comment.