jest icon indicating copy to clipboard operation
jest copied to clipboard

Jest not transpiling an imported javascript file in a different directory

Open kepeterson opened this issue 5 years ago • 8 comments

🐛 Bug Report

I have a jest project using a directory structure that looks like this

Project A
|
|- .babelrc
|- package.json (with jest config)
|
 -components
  |
  |- Card.jsx

 -__tests__
  |
  |- Card.test.jsx

shared
|
|- .babelrc
|
|- constants
  |
  | - user.js

Card.jsx imports some values from user.js which uses ES6 modules. Card.jsx imports using a relative import path import { settings } from '../../shared/constants/users'. When I run jest, I get the following error when user.js attempts to import from another file:

import { membershipStatuses } from './orgs';           
       ^

SyntaxError: Unexpected token {

  3 | 
  4 | 
> 5 | import { settings } from '../../shared/constants/users';
    | ^


  at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
  at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
  at Object.<anonymous> (components/SidenavContactCard.jsx:5:1)

It seems to me that Jest is not transpiling files in other directories outside of the root of the jest project. How do I configure Jest to make this work?

Expected behavior

Jest and Babel work together to transpile user.js properly.

Run npx envinfo --preset jest

Paste the results here:

  System:
    OS: macOS 10.14.5
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 10.13.0 - ~/.nvm/versions/node/v10.13.0/bin/node
    Yarn: 1.10.1 - ~/.nvm/versions/node/v10.13.0/bin/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v10.13.0/bin/npm
  npmPackages:
    jest: ^24.8.0 => 24.8.0 

jest --debug

> jest "--debug"

{
  "configs": [
    {
      "automock": false,
      "browser": false,
      "cache": true,
      "cacheDirectory": "/private/var/folders/sr/mvj8wg_n6s1b7jqpd9vjxc1m0000gn/T/jest_dx",
      "clearMocks": true,
      "coveragePathIgnorePatterns": [
        "/node_modules/"
      ],
      "cwd": "/Users/kyle/Code/spoke/clients/next",
      "dependencyExtractor": null,
      "detectLeaks": false,
      "detectOpenHandles": false,
      "errorOnDeprecated": false,
      "filter": null,
      "forceCoverageMatch": [],
      "globalSetup": null,
      "globalTeardown": null,
      "globals": {},
      "haste": {
        "computeSha1": false,
        "providesModuleNodeModules": [],
        "throwOnModuleCollision": false
      },
      "moduleDirectories": [
        "node_modules"
      ],
      "moduleFileExtensions": [
        "js",
        "json",
        "jsx",
        "ts",
        "tsx",
        "node"
      ],
      "moduleNameMapper": {},
      "modulePathIgnorePatterns": [],
      "name": "6cb406f566a4d486a3b72451e6d0fd85",
      "prettierPath": "prettier",
      "resetMocks": false,
      "resetModules": false,
      "resolver": null,
      "restoreMocks": false,
      "rootDir": "/Users/kyle/Code/spoke/clients/next",
      "roots": [
        "/Users/kyle/Code/spoke/clients/next"
      ],
      "runner": "jest-runner",
      "setupFiles": [],
      "setupFilesAfterEnv": [],
      "skipFilter": false,
      "snapshotSerializers": [],
      "testEnvironment": "/Users/kyle/Code/spoke/clients/next/node_modules/jest-environment-jsdom/build/index.js",
      "testEnvironmentOptions": {},
      "testLocationInResults": false,
      "testMatch": [
        "**/__tests__/**/*.[jt]s?(x)",
        "**/?(*.)+(spec|test).[tj]s?(x)"
      ],
      "testPathIgnorePatterns": [
        "/node_modules/"
      ],
      "testRegex": [],
      "testRunner": "/Users/kyle/Code/spoke/clients/next/node_modules/jest-jasmine2/build/index.js",
      "testURL": "http://localhost",
      "timers": "real",
      "transform": [
        [
          "^.+\\.[jt]sx?$",
          "/Users/kyle/Code/spoke/clients/next/node_modules/jest-config/node_modules/babel-jest/build/index.js"
        ]
      ],
      "transformIgnorePatterns": [
        "/node_modules/"
      ],
      "watchPathIgnorePatterns": []
    }
  ],
  "globalConfig": {
    "bail": 0,
    "changedFilesWithAncestor": false,
    "collectCoverage": false,
    "collectCoverageFrom": null,
    "coverageDirectory": "/Users/kyle/Code/spoke/clients/next/coverage",
    "coverageReporters": [
      "json",
      "text",
      "lcov",
      "clover"
    ],
    "coverageThreshold": null,
    "detectLeaks": false,
    "detectOpenHandles": false,
    "errorOnDeprecated": false,
    "expand": false,
    "filter": null,
    "globalSetup": null,
    "globalTeardown": null,
    "json": false,
    "listTests": false,
    "maxConcurrency": 5,
    "maxWorkers": 11,
    "noStackTrace": false,
    "nonFlagArgs": [],
    "notify": false,
    "notifyMode": "failure-change",
    "passWithNoTests": false,
    "projects": null,
    "rootDir": "/Users/kyle/Code/spoke/clients/next",
    "runTestsByPath": false,
    "skipFilter": false,
    "testFailureExitCode": 1,
    "testPathPattern": "",
    "testResultsProcessor": null,
    "testSequencer": "/Users/kyle/Code/spoke/clients/next/node_modules/@jest/test-sequencer/build/index.js",
    "updateSnapshot": "new",
    "useStderr": false,
    "verbose": null,
    "watch": false,
    "watchman": true
  },
  "version": "24.8.0"
}

kepeterson avatar Jul 01 '19 17:07 kepeterson

you should use babel.config.js not .babelrc

yeongjet avatar Jul 06 '19 08:07 yeongjet

Why can't I use .babelrc? It's a valid way to configure babel https://babeljs.io/docs/en/configuration

And the code compiles when webpack'd using my current babel config, so I don't think it's an issue with that. This issue only happens when trying to run a test with Jest.

kepeterson avatar Jul 09 '19 20:07 kepeterson

I have exactly the problem, as described above.

you should use babel.config.js not .babelrc

...as suggested by yeongjet, solved my issue. Just rename the file, and do a module.exports = ...

mjashanks avatar Aug 05 '19 06:08 mjashanks

I have the same issue with babel.config.js. Any ideas why?

zquintana avatar Jun 09 '20 20:06 zquintana

same here

subhasishdas159 avatar Oct 13 '20 12:10 subhasishdas159

Having the same issue here using babel.config.js.

yaololo avatar Jan 12 '21 06:01 yaololo

The problem that I've identified is that when we choose a configFile in babel-jest settings we skip the scanning for the root babel.config.js config file for some reason and don't use any of the shared monorepo babel configs anymore.

However if we choose rootMode: 'upward', babelrc: true, without explicitly setting a configFile, then when a file from the root node_modules needs to be transpiled, it fails. This is because the .babelrc rules doesn't apply to it, because it's not relative to it. Instead, only the root babel.config.js is applied to it. In our case: ../../node_modules/@react-native/polyfills/error-guard.js is not relevant to the package, so only the root one is applied to it.

So the solution for me was to use the second option but to make sure that the module:metro-react-native-babel-preset is guaranteed to parse that package. This can be reproduced for other packages that needs babel plugins to be parsed-

  • In the monorepo package:
transform: {
    // Make sure to use the exact regex `^.+\\.(js|ts|tsx)$` here and not any other version like `^.+\\.(js|tsx?)$`. Otherwise it will get overridden by a default that ignores the `babel-jest` configs.
    '^.+\\.(js|ts|tsx)$': [
      'babel-jest',
      {
        cwd: __dirname,
        rootMode: 'upward',
        babelrc: true,
       }
    ],
  },
  • In the root babel.config.js:

// (\\{1,2}|\/) - it turns out that windows uses both \ and \\ as the path separators, and mac uses /
const reactNativePathRegex =
  /node_modules(\\{1,2}|\/)(@react-native|react-native)/;

// ...
    overrides: [
      {
        include: [reactNativePathRegex],
        presets: ['module:metro-react-native-babel-preset'],
      },
    ],
// ...

vzaidman avatar Jan 09 '23 18:01 vzaidman

Another way to solve this would be to configure the whole babel resolution manually:

babel.config.js:

    // remove this from the root babel.config.js
    // babelrc: true,
    // babelrcRoots: [
    //   './packages/*',
    // ],

add the following to .babelrc.js:

  extends: '../../babel.config.js',

then in jest.config.js:

transform: {
    // Make sure to use the exact regex `^.+\\.(js|ts|tsx)$` here and not any other version like `^.+\\.(js|tsx?)$`. Otherwise it will get overridden by a default that ignores the `babel-jest` configs.
    '^.+\\.(js|ts|tsx)$': [
      'babel-jest',
      {
        cwd: __dirname,
        configFile: './.babelrc.js',
       }
    ],
  },

vzaidman avatar Jan 11 '23 10:01 vzaidman

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Jan 18 '24 17:01 github-actions[bot]

This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.

github-actions[bot] avatar Feb 17 '24 18:02 github-actions[bot]

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[bot] avatar Mar 19 '24 00:03 github-actions[bot]