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

[babel-jest] Feature: support expanded .babelrc.js api #5324

Closed
simonbuchan opened this issue Jan 16, 2018 · 5 comments
Closed

[babel-jest] Feature: support expanded .babelrc.js api #5324

simonbuchan opened this issue Jan 16, 2018 · 5 comments

Comments

@simonbuchan
Copy link

Do you want to request a feature or report a bug?
Feature.

What is the current behavior?
.babelrc.js export is flattened to JSON

This effectively ignores any features you would use .babelrc.js for, and shows up as things like unexpected token 'import' when the function export is treated as an empty config, or overrides are ignored because RegExp tests are stripped, etc..., so no transforms are run.

What is the expected behavior?

In short, babel-jest looks like it should be using the new loadOptions() API in @babel/core with at least { babelrc: true, filename, envName: 'test' }, though it is not documented yet 😟

Please provide your exact Jest configuration and mention your Jest, node,
yarn/npm version and operating system.

// package.json
{
  "private": true,
  "devDependencies": {
    "@babel/core": "7.0.0-beta.37",
    "@babel/preset-env": "7.0.0-beta.37",
    "@babel/preset-flow": "7.0.0-beta.37",
    "@babel/preset-react": "7.0.0-beta.37",
    "@babel/preset-stage-3": "7.0.0-beta.37",
    "@babel/preset-typescript": "7.0.0-beta.37",
    "babel-jest": "22.0.6",
    "jest": "22.0.6"
  }
}

// .babelrc.js example
module.exports = api => {
  // Can also use arbitrary tests with `const val = api.cache(() => expr)`
  const env = api.env();

  // Jest needs CommonJS, but otherwise we want webpack to see ES modules.
  const modules = env === 'test' ? 'commonjs' : false;

  const targets = env === 'test'
    ? { node: 'current' }
    : { browsers: ['> 5%', 'IE 11'] };

  const presets = [
    ['@babel/env', { modules, useBuiltIns: 'usage', targets }],
    '@babel/stage-3',
  ];

  return {
    overrides: [
      { test: /\.jsx?$/, presets: [...presets, '@babel/flow', '@babel/react'] },
      { test: /\.ts$/, presets: [...presets, '@babel/typescript'] },
      { test: /\.tsx$/, presets: [...presets, '@babel/typescript', '@babel/react'] },
    ],
  };
};

Example loadOptions() usage:

> node -p "require('@babel/core').loadOptions({ babelrc: true, filename: 'src/index.js', envName: 'test' })"
{ plugins:
   [ Plugin {
       key: 'C:\\code\\skilitics\\prototypes\\layout\\node_modules\\@babel\\preset-react\\lib\\index.js$0',
       manipulateOptions: [Function: manipulateOptions],
       post: undefined,
       pre: undefined,
       visitor: [Object],
       parserOverride: undefined,
       generatorOverride: undefined,
       options: [Object] },
<snip>
     Plugin {
       key: 'use-built-ins',
       manipulateOptions: undefined,
       post: [Function: post],
       pre: [Function: pre],
       visitor: [Object],
       parserOverride: undefined,
       generatorOverride: undefined,
       options: [Object] } ],
  overrides:
   [ { test: /\.jsx?$/, presets: [Object] },
     { test: /\.ts$/, presets: [Object] },
     { test: /\.tsx$/, presets: [Object] } ],
  test: /\.jsx?$/,
  babelrc: false,
  filename: 'src/index.js',
  envName: 'test',
  presets: [],
  passPerPreset: false,
  cwd: 'C:\\code\\skilitics\\prototypes\\layout' }
@simonbuchan
Copy link
Author

If it helps, here's a transform file that looks like it works for our case, though we'll probably need more tweaks:

/**
 * A variant of babel-jest that will process some files with babel@6 and some with babel@7
 * This code is based on babel-jest: https://github.com/facebook/jest/blob/master/packages/babel-jest/src/index.js
 * TODO: Support instrument
 */

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const util = require('util');

const babel6 = require('babel-core');
const babel7 = require('@babel/core');
const jestPreset = require('babel-preset-jest');

const thisFileContent = fs.readFileSync(__filename);

function isBabel6Filename(filename) {
  return filename.startsWith(modulesPath);
}

function applyJestOptions(babelOptions) {
  babelOptions.presets = (babelOptions.presets || []).concat(jestPreset);
  babelOptions.retainLines = true;
  babelOptions.sourceMaps = 'inline';
}

const modulesPath = path.join(__dirname, 'node_modules');

const babel6Options = {
  presets: ['react-native'],
};

applyJestOptions(babel6Options);

function getBabel7Options(filename) {
  const babel7Options = babel7.loadOptions({
    babelrc: true,
    filename,
    envName: 'test',
  });
  applyJestOptions(babel7Options);
  return babel7Options;
}

function processBabel6(src, filename, config) {
  if (!babel6.util.canCompile(filename, config.moduleFileExtensions.map(x => `.${x}`))) {
    return src;
  }

  return babel6.transform(src, babel6Options).code;
}

function processBabel7(src, filename) {
  const babel7Options = getBabel7Options(filename);
  const result = babel7.transform(src, babel7Options);
  return result ? result.code : src;
}

function process(src, filename, config, transformOptions) {
  if (isBabel6Filename(filename)) {
    return processBabel6(src, filename, config);
  } else {
    return processBabel7(src, filename);
  }
}

function getCacheKey(fileData, filename, configString, {instrument}) {
  return crypto
    .createHash('md5')
    .update(thisFileContent)
    .update('\0', 'utf8')
    .update(fileData)
    .update('\0', 'utf8')
    .update(filename)
    .update('\0', 'utf8')
    .update(configString)
    .update('\0', 'utf8')
    // util.inspect() shows more things than JSON.stringify().
    .update(util.inspect(
      isBabel6Filename(filename) ? babel6Options : getBabel7Options(filename),
      { depth: null, colors: false }))
    .update('\0', 'utf8')
    .update(instrument ? 'instrument' : '')
    .digest('hex');
}

module.exports = { getCacheKey, process };

@Jaid
Copy link

Jaid commented Jan 20, 2018

@simonbuchan That works, thank you! I added your tweaked transform code as jest.transform.js and referenced it in my config.

// jest.config.js

const transform = {
    ".*": "./jest.transform.js"
}

module.exports = {transform}

@SimenB
Copy link
Member

SimenB commented Mar 5, 2018

There's an incoming API in Babel 7 we could use (it documents the API mentioned in the OP): babel/babel#7472

Some way of serializing the return value there into something that is not lossy would be great

@SimenB
Copy link
Member

SimenB commented Feb 3, 2019

This is fixed in Jest 24 which uses Babel's own API (the one I linked above) to load Babel config

@SimenB SimenB closed this as completed Feb 3, 2019
agilgur5 added a commit to agilgur5/react-signature-canvas that referenced this issue Jul 28, 2019
- add 1 simple test for existence of canvas and instance methods

- change test script to use jest, and move prev test to test:pub
  - change CI to run test and test:pub
- configure jest and enzyme for testing usage
  - make jest importable too
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader because babel-loader@6
      has some bugs with it and @7 doesn't support webpack@1
      - babel/babel-loader#552

- use jest instead of ava mainly because there's less to
  configure / install (directly at least, still a lot indirectly),
  it's popular / well-supported in React community, and supports
  configuration outside of package.json
  - see #33 for some more details

(deps): add jest, enzyme, and supporting deps to devDeps
- add babel-jest@23 for Babel 6 support
  - and configure it for .js files due to a jest bug
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
- add enzyme-adapter-react-16 to configure Enzyme with React 16
  - upgrade to React 16 in devDeps bc adapter-react-15 requires
    react-test-renderer and no drawbacks in upgrading
agilgur5 added a commit to agilgur5/react-signature-canvas that referenced this issue Jul 28, 2019
- add 1 simple test for existence of canvas and instance methods

- change test script to use jest, and move prev test to test:pub
  - change CI to run test and test:pub
- configure jest and enzyme for testing usage
  - make jest importable too
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader because babel-loader@6
      has some bugs with it and @7 doesn't support webpack@1
      - babel/babel-loader#552

- use jest instead of ava mainly because there's less to
  configure / install (directly at least, still a lot indirectly),
  it's popular / well-supported in React community, and supports
  configuration outside of package.json
  - see #33 for some more details

(deps): add jest, enzyme, and supporting deps to devDeps
- add babel-jest@23 for Babel 6 support
  - and configure it for .js files due to a jest bug
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
- add enzyme-adapter-react-16 to configure Enzyme with React 16
  - upgrade to React 16 in devDeps bc adapter-react-15 requires
    react-test-renderer and no drawbacks in upgrading
agilgur5 added a commit to agilgur5/react-signature-canvas that referenced this issue Jul 28, 2019
- add 1 simple test for existence of canvas and instance methods
  - (pkg): test code shouldn't be in the package, just source
    - currently preferring to keep source and tests co-located

- change test script to use jest, and move prev test to test:pub
  - change CI to run test and test:pub
- configure jest and enzyme for testing usage
  - make jest importable too
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader because babel-loader@6
      has some bugs with it and @7 doesn't support webpack@1
      - babel/babel-loader#552

- use jest instead of ava mainly because there's less to
  configure / install (directly at least, still a lot indirectly),
  it's popular / well-supported in React community, and supports
  configuration outside of package.json
  - see #33 for some more details

(deps): add jest, enzyme, and supporting deps to devDeps
- add babel-jest@23 for Babel 6 support
  - and configure it for .js files due to a jest bug
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
- add enzyme-adapter-react-16 to configure Enzyme with React 16
  - upgrade to React 16 in devDeps bc adapter-react-15 requires
    react-test-renderer and no drawbacks in upgrading
agilgur5 added a commit to agilgur5/react-signature-canvas that referenced this issue Jul 29, 2019
- add 1 simple test for existence of canvas and instance methods
  - (pkg): test code shouldn't be in the package, just source
    - currently preferring to keep source and tests co-located

- change test script to use jest, and move prev test to test:pub
  - (ci): change CI to run test and test:pub
- configure jest and enzyme for testing usage
  - make jest importable too
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader because babel-loader@6
      has some bugs with it and @7 doesn't support webpack@1
      - babel/babel-loader#552

- use jest instead of ava mainly because there's less to
  configure / install (directly at least, still a lot indirectly),
  it's popular / well-supported in React community, and supports
  configuration outside of package.json
  - see #33 for some more details

(deps): add jest, enzyme, and supporting deps to devDeps
- add babel-jest@23 for Babel 6 support
  - and configure it for .js files due to a jest bug
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
- add enzyme-adapter-react-16 to configure Enzyme with React 16
  - upgrade to React 16 in devDeps bc adapter-react-15 requires
    react-test-renderer and no drawbacks in upgrading
agilgur5 added a commit to agilgur5/react-signature-canvas that referenced this issue Aug 4, 2019
- add 1 simple test for existence of canvas and instance methods
  - (pkg): test code shouldn't be in the package, just source
    - currently preferring to keep source and tests co-located

- change test script to use jest, and move prev test to test:pub
  - (ci): change CI to run test and test:pub
- configure jest and enzyme for testing usage
  - make jest importable too
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader because babel-loader@6
      has some bugs with it and @7 doesn't support webpack@1
      - babel/babel-loader#552

- use jest instead of ava mainly because there's less to
  configure / install (directly at least, still a lot indirectly),
  it's popular / well-supported in React community, and supports
  configuration outside of package.json
  - see #33 for some more details

(deps): add jest, enzyme, and supporting deps to devDeps
- add babel-jest@23 for Babel 6 support
  - and configure it for .js files due to a jest bug
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
- add enzyme-adapter-react-16 to configure Enzyme with React 16
  - upgrade to React 16 in devDeps bc adapter-react-15 requires
    react-test-renderer and no drawbacks in upgrading
agilgur5 added a commit to agilgur5/trim-canvas that referenced this issue Nov 30, 2019
- ensure that width/height of canvas are trimmed down after drawing a
  purple rectangle in the center

- add test script that uses jest
  - (ci): change CI to run test and test:pub
- configure jest and babel-jest
  - add coverage/ directory to gitignore
  - add babel-jest@23 for Babel 6 support
    - and configure it for .js files due to a jest bug
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader (have to duplicate config)
      because babel-loader@6 has some bugs with it and babel-loader@7
      doesn't support webpack@1
      - babel/babel-loader#552

(deps): add jest, babel-jest, and canvas-prebuilt to devDeps
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
agilgur5 added a commit to agilgur5/trim-canvas that referenced this issue Nov 30, 2019
- ensure that width/height of canvas are trimmed down after drawing a
  purple rectangle in the center

- add test script that uses jest
  - (ci): change CI to run test and test:pub
- configure jest and babel-jest
  - add coverage/ directory to gitignore
  - add babel-jest@23 for Babel 6 support
    - and configure it for .js files due to a jest bug
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader (have to duplicate config)
      because babel-loader@6 has some bugs with it and babel-loader@7
      doesn't support webpack@1
      - babel/babel-loader#552

(deps): add jest, babel-jest, and canvas-prebuilt to devDeps
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
agilgur5 added a commit to agilgur5/trim-canvas that referenced this issue Dec 1, 2019
- ensure that width/height of canvas are trimmed down after drawing a
  purple rectangle in the center

- add test script that uses jest
  - (ci): change CI to run test and test:pub
- configure jest and babel-jest
  - add coverage/ directory to gitignore
  - add babel-jest@23 for Babel 6 support
    - and configure it for .js files due to a jest bug
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader (have to duplicate config)
      because babel-loader@6 has some bugs with it and babel-loader@7
      doesn't support webpack@1
      - babel/babel-loader#552

(deps): add jest, babel-jest, and canvas-prebuilt to devDeps
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
agilgur5 added a commit to agilgur5/trim-canvas that referenced this issue Dec 3, 2019
- ensure that width/height of canvas are trimmed down after drawing a
  purple rectangle in the center

- add test script that uses jest
  - (ci): change CI to run test and test:pub
- configure jest and babel-jest
  - add coverage/ directory to gitignore
  - add babel-jest@23 for Babel 6 support
    - and configure it for .js files due to a jest bug
  - add .babelrc to configure babel-jest
    - can't use .babelrc.js as babel-jest@23 doesn't support it
      - jestjs/jest#5324
    - can't use .babelrc for babel-loader (have to duplicate config)
      because babel-loader@6 has some bugs with it and babel-loader@7
      doesn't support webpack@1
      - babel/babel-loader#552

(deps): add jest, babel-jest, and canvas-prebuilt to devDeps
- add canvas-prebuilt@1 to support jest's jsdom v11
  - canvas is used by jsdom for, well, canvas interactions
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants