1

语境

我们的团队刚刚继承了一个 React-Native(不是 Expo)、Typescript 代码库,没有对 TSX 进行任何测试。我们目前正在尝试为某些钩子设置第一组测试,但无法运行它们。其他不涉及 TSX 和 react-native 依赖项的单元测试正在运行,没有任何问题。

我们收到以下错误:

Details:

    /Users/<username>/Repos/<client>/<project>/clients/mobile-app/node_modules/launchdarkly-react-native-client-sdk/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      1 | import React, { useEffect, useState, useContext } from 'react';
    > 2 | import LDClient, {
        | ^
      3 |   LDUserConfig,
      4 |   LDClientConfig,
      5 | } from 'launchdarkly-react-native-client-sdk';

      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1479:14)
      at Object.<anonymous> (src/feature-flags.tsx:2:1)

从我读到的关于这个主题和错误的内容来看,依赖项似乎launchdarkly-react-native-client-sdk没有被转换,因为node_modules默认情况下它们没有被 jest 转换。关于这个主题有很多信息,我已经尝试了许多建议的解决方案,但我无法使任何工作。我很确定我忽略了一些简单的事情,但任何帮助将不胜感激。


代码

package.json - 笑话配置

"jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['relay', 'transform-inline-environment-variables'],
};

特征标志.test.tsx

import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
import { FeatureFlagContext, useBooleanFlag } from './feature-flags';
import LDClient from 'launchdarkly-react-native-client-sdk';

const wrapper =
  (client: LDClient | null): React.FC =>
  ({ children }) => {
    return (
      <FeatureFlagContext.Provider value={{ client, userIdentified: false }}>
        {children}
      </FeatureFlagContext.Provider>
    );
  };

describe('useBooleanFlag', () => {
  test('if client is null (iOS), return loading state', () => {
    const { result } = renderHook(() => useBooleanFlag('competitions'), {
      wrapper: wrapper(null),
    });

    expect(result.current.isLoading).toBe(true);
  });
});

尝试过的解决方案

不幸的是,这个错误似乎很笼统,这使得对修复的研究变得更加麻烦。我们尝试了以下方法:

  1. 显式转换 LaunchDarkly 依赖项。不确定该模式是否真的有效,只能在这里测试,并没有找到在本地验证它的方法。返回相同的错误。

包.json

"jest": {
    <same as first package.json>
    "transform": {
      "^.+\\/(launchdarkly-react-native-client-sdk)\\/.+$": "babel-jest"
    }
  }
  1. 显式地改变一切。返回相同的错误。
"jest": {
    <same as first package.json>
    "transform": {
      "^.+\\.(js|ts)x?$": "babel-jest"
    }
  }
  1. 显式转换除 exclude 之外的所有内容node_modules。打破所有测试。
"jest": {
    <same as first package.json>
"transform": {
      "^.+\\.(js|ts)x?$": "babel-jest"
    }
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|<other packages>)"
    ]
  }
  1. 调整 babel.config.js
  presets: [
    'module:metro-react-native-babel-preset',
    '@babel/preset-env',
    { modules: 'auto' },
  ],
  plugins: ['relay', 'transform-inline-environment-variables'],
};
  1. 仅包含基于解决方案的 transformIgnorePatterns。导致所有测试失败。

  2. 仅通过 CLI 忽略包名称(作为健全性检查)yarn test --transformIgnorePatterns 'node_modules/(?react-native-client-sdk)/'会导致不同的错误。建议在这里

Invariant Violation: Native module cannot be null.

      at invariant (node_modules/invariant/invariant.js:40:15)
      at new NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:49:7)
      at RNFBNativeEventEmitter._createSuperInternal (node_modules/@react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:22:311)
      at new RNFBNativeEventEmitter (node_modules/@react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:24:5)
      at Object.<anonymous> (node_modules/@react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:75:16)
      at Object.<anonymous> (node_modules/@react-native-firebase/app/lib/internal/registry/nativeModule.js:21:1)

这似乎合乎逻辑。

结论

如您所见,我完全迷失了。配置这些东西我知之甚少,因此我决定尝试看似适得其反的东西。任何帮助将不胜感激。

4

0 回答 0