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

feat: create new @jest/transform package #7915

Merged
merged 3 commits into from Feb 16, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -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` ([#7915](https://github.com/facebook/jest/pull/7915))

### 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",
SimenB marked this conversation as resolved.
Show resolved Hide resolved
"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"
Copy link
Collaborator

Choose a reason for hiding this comment

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

looks like lerna leftover

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, not sure what purpose it serves, but I don't wanna delete it

}
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,
|};