语境
我们的团队刚刚继承了一个 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);
});
});
尝试过的解决方案
不幸的是,这个错误似乎很笼统,这使得对修复的研究变得更加麻烦。我们尝试了以下方法:
- 显式转换 LaunchDarkly 依赖项。不确定该模式是否真的有效,只能在这里测试,并没有找到在本地验证它的方法。返回相同的错误。
包.json
"jest": {
<same as first package.json>
"transform": {
"^.+\\/(launchdarkly-react-native-client-sdk)\\/.+$": "babel-jest"
}
}
- 显式地改变一切。返回相同的错误。
"jest": {
<same as first package.json>
"transform": {
"^.+\\.(js|ts)x?$": "babel-jest"
}
}
- 显式转换除 exclude 之外的所有内容
node_modules
。打破所有测试。
"jest": {
<same as first package.json>
"transform": {
"^.+\\.(js|ts)x?$": "babel-jest"
}
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|<other packages>)"
]
}
- 调整 babel.config.js
presets: [
'module:metro-react-native-babel-preset',
'@babel/preset-env',
{ modules: 'auto' },
],
plugins: ['relay', 'transform-inline-environment-variables'],
};
仅包含基于此解决方案的 transformIgnorePatterns。导致所有测试失败。
仅通过 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)
这似乎合乎逻辑。
结论
如您所见,我完全迷失了。配置这些东西我知之甚少,因此我决定尝试看似适得其反的东西。任何帮助将不胜感激。