How to configure Jest to transform modules containing invalid syntax?

Viewed 8659

I've forked the following react native base project and converted it from JavaScript to TypeScript. The app runs correctly but Jest tests fail with the following error. I expected the test to run successfully and Jest to run any transforms where necessary:

 C:\Users\brian-varley\Documents\Projects\react-native-base\node_modules\redux-flipper\node_modules\react-native-flipper\index.js:11
import {NativeModules, NativeEventEmitter} from 'react-native';
^^^^^^

SyntaxError: Cannot use import statement outside a module

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (node_modules/redux-flipper/lib/index.js:3:32)

The cause of the error seems to come from this import statement inside the react-native-flipper package:

import {NativeModules, NativeEventEmitter} from 'react-native';

I've tried a solution here from StackOverflow which suggests using babel-jestas the transformer in the jest.config.js file to no avail - https://stackoverflow.com/a/64223627/1829251. I also looked through this thread but didn't find a solution - https://github.com/facebook/jest/issues/9292

Question:

How can you configure Jest to transform modules containing invalid syntax?

Environment

"react-native": "0.63.2",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "0.59.0",
"babel-jest": "^25.1.0",
"ts-jest": "^26.5.3",

Config Code Samples:

jest.config.js:

module.exports =  {
    preset: "react-native",
    transform: {
      "^.+\\.tsx?$": "ts-jest",
      "^.+\\.(js|jsx)$": "babel-jest",
      "node_modules/variables/.+\\.(j|t)sx?$": "babel-jest"
    },
    testRegex: "(/src/.*\\.(test|spec))\\.(jsx?|tsx?|ts|js)$",
    transformIgnorePatterns: [
      "node_modules/(?!(jest-)?react-native|react-(native|universal|navigation)-(.*)|@react-native-community/(.*)|@react-navigation/(.*)|bs-platform|@rootstrap/redux-tools)"
    ],
    setupFiles: [
      "./tests/__mocks__/index.js",
      "<rootDir>/node_modules/react-native-gesture-handler/jestSetup.js"
    ],
    moduleFileExtensions: [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }

babel.config.js:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        alias: {
          actions: './src/actions',
          httpClient: './src/httpClient',
          services: './src/services',
          components: './src/components',
          constants: './src/constants',
          screens: './src/screens',
          hooks: './src/hooks',
          locale: './src/locale',
          reducers: './src/reducers',
          selectors: './src/selectors',
          store: './src/store',
          utils: './src/utils',
          navigators: './src/navigators',
          validations: './src/validations',
        },
      },
    ],
  ],
};

tsconfig.json:

{
    "compilerOptions": {
      "target": "es6",
      "module": "commonjs",
      "moduleResolution": "node",
      "jsx": "react",
      "outDir": "./dist",
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true,
      "allowSyntheticDefaultImports": true,
      "strict": true,
      "skipLibCheck": true,
      "declaration": true,
      "noUnusedLocals": true,
      "suppressImplicitAnyIndexErrors": true,
      "baseUrl": "./",
    },
    "exclude": [
      "node_modules",
    ]
  }
1 Answers
module.exports =  {
preset: "react-native",
transform: {
    "^.+\\.ts?$": "ts-jest",
    "^.+\\.tsx?$": "ts-jest",
    "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
  },
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)?$",
  transformIgnorePatterns: [
    "node_modules/(?!(jest-)?react-native|react-(native|universal|navigation)-(.*)|@react-native-community/(.*)|@react-navigation/(.*)|bs-platform|@rootstrap/redux-tools)"
  ],
  setupFiles: [
    "./tests/__mocks__/index.js",
    "<rootDir>/node_modules/react-native-gesture-handler/jestSetup.js"
  ],
  moduleFileExtensions: [
    "ts",
    "tsx",
    "js",
    "jsx",
    "json",
    "node"
  ],
  moduleNameMapper: {
    "^.+\\.(css|less|scss)$": "identity-obj-proxy"
  },
  moduleDirectories: [
    "node_modules",
    "src"
  ],
  }

Can you please try this file and try to create new test.

Related