ts-jest: Forced commonjs breaks synthetic default imports

  • Issue

My React Native code writes imports as follows:

import React from "react";
import RN from "react-native";

...

class MyComponent extends React.Component<{}, {}> {

This works fine in the app, but fails in Jest with the error Cannot read property 'Component' of undefined. This seems to be because while my app’s tsconfig has "module": "es6" and relies on Babel to convert the import statements, ts-jest forces commonjs which translates this to

const react_1 = require("react");

...

class MyComponent extends react_1.default.Component {

which is of course wrong. Until recently, I worked around this by writing a preprocessor which would run ts-jest and babel-jest in sequence, but this has been broken by the change https://github.com/kulshekhar/ts-jest/commit/192b493af8843a2387476d8de9a474067afc229e, which forces commonjs even if my tsconfig says otherwise.

You might ask why I don’t just write import * as RN from "react-native" instead? Because of https://github.com/facebook/react-native/issues/12018. Besides, this conceptually makes for a better test in my mind- the app and the test code go through the same transformation pipeline (TypeScript followed by Babel).

  • Expected behavior

There should be a way to override the "module": "commonjs" setting.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 27 (19 by maintainers)

Commits related to this issue

Most upvoted comments

esModuleInterop": true was the key for me. Thank you @diegoddox!

@blujedis I can’t remember exactly since was a while ago but here is the new config.

"jest": {
    "preset": "react-native",
    "verbose": true,
    "setupFiles": [
      "./setupJest.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-navigation)"
    ],
    "testPathIgnorePatterns": [
      "build",
      "tests",
      "node_modules/"
    ],
    "cacheDirectory": ".jest/cache",
    "transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|png)$": "jest-transform-stub",
      "^.+\\.tsx?$": "ts-jest"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "moduleFileExtensions": [
      "ts",
      "js",
      "jsx",
      "tsx",
      "json",
      "node"
    ],
    "globals": {
      "__DEV__": true,
      "ts-jest": {
        "useBabelrc": true,
        "tsConfigFile": "tsconfig.test.json"
      }
    }
  }

tsconfig.test.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true
  }
}

@ds300 Awesome that works! Will send a pr for the README.

Same from the README.

{
  "jest": {
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      ".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ]
  }
}

@ds300 Nah bro. I ended up scrapping running my tests on the typescript and instead run them on the compiled javascript instead.

@kulshekhar This works perfectly and solves my problem. Thank you very much for the quick response, I really appreciate it!