更新:错误报告并链接到最小可重复的演示can be found here
我们将Expo项目转换为TypeScript。我们还希望Jest测试以TypeScript编写。但是,无论我们使用ts-jest还是babel打字稿预设,expo本地化库和expo矢量图标都不会消失。
每项测试中使用带有(expo-vector-)图标的组件的测试
FAIL src/ui/shared/Popover/Popover.test.tsx
● Test suite failed to run
/Users/gilliamf/Projects/bgp/node_modules/@expo/vector-icons/build/AntDesign.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import createIconSet from './createIconSet';
^^^^^^^^^^^^^
SyntaxError: Unexpected identifier
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> (node_modules/@expo/vector-icons/src/Icons.ts:1:1)
每项测试中都使用expo-localization
FAIL src/services/__tests__/TranslationService.test.ts
● Test suite failed to run
/Users/gilliamf/Projects/bgp/node_modules/expo-localization/build/Localization.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import ExpoLocalization from './ExpoLocalization';
^^^^^^^^^^^^^^^^
SyntaxError: Unexpected identifier
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> (src/translations/i18next.ts:907:25)
我们开始使用ts-jest。尝试了许多不同的TypeScript配置(tsconfig.jest.json)。 尝试转换为babel-typescript-preset,相同的错误。 尝试了所有不同类型的babel配置(babel.config.js)。 最终切换回ts-jest,但问题仍然存在。似乎在expo-localization和expo-vector-icons库中有 import语句,而babel由于某种原因而无法将其翻译。
如果要重现此问题,请使用Expo启动TypeScript项目并测试包含以下两个导入之一的任何内容:
import { locale } from 'expo-localization';
import { createIconSetFromIcoMoon } from '@expo/vector-icons';
当前依赖项,babel配置和ts配置:
babel.config.js
module.exports = function(api) {
api.cache.never();
return {
presets: ['babel-preset-expo'],
plugins: [
'@babel/plugin-transform-flow-strip-types',
[
'module-resolver',
{
root: ['.'],
alias: {
components: './src/ui/components',
shared: './src/ui/shared',
screens: './src/ui/screens',
utils: './src/utils',
styles: './src/styles',
services: './src/services',
stores: './src/stores',
assets: './src/assets',
navigators: './src/navigators',
hoc: './src/HOC',
translations: './src/translations',
constants: './src/constants'
}
}
]
]
};
};
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"components/*": ["./src/ui/components/*"],
"shared/*": ["./src/ui/shared/*"],
"screens/*": ["./src/ui/screens/*"],
"utils/*": ["./src/utils/*"],
"styles/*": ["./src/styles/*"],
"services/*": ["./src/services/*"],
"stores/*": ["./src/stores/*"],
"assets/*": ["./src/assets/*"],
"navigators/*": ["./src/navigators/*"],
"hoc/*": ["./src/HOC/*"],
"translations/*": ["./src/translations/*"],
"constants/*": ["./src/constants/*"]
},
"noEmit": true,
"lib": ["dom", "esnext"],
"jsx": "react-native",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"importHelpers": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"strict": true,
"experimentalDecorators": true,
"resolveJsonModule": true
}
}
tsconfig.jest.json
{
"extends": "./tsconfig",
"compilerOptions": {
"jsx": "react",
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"importHelpers": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"strict": true,
"experimentalDecorators": true,
"resolveJsonModule": true
}
}
package.json (但是,由于反复试验和试用期长,其中可能有很多东西可以使用,但这仅用于版本参考)
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"expo": "expo",
"start": "expo start -c",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"build:ios": "expo build:ios",
"build:android": "expo build:android",
"build:download": "expo build:status | egrep -o 'https?://[^ ]+\\.(apk|ipa)' | head -n 1 | curl -L \"$(</dev/stdin)\"",
"start:ci": "sudo sysctl -w kern.maxfiles=5242880 && sudo sysctl -w kern.maxfilesperproc=524288 && sudo react-native-scripts start",
"jest": "jest",
"jest:cache": "jest --clearCache",
"jest:migrate-config": "ts-jest config:migrate jest.config.js",
"test": "jest --ci --reporters=jest-junit --reporters=default --coverage --coverageReporters=cobertura --coverageReporters=html --coverageReporters=text",
"expo:login": "expo login --non-interactive",
"expo:logout": "expo logout",
"publish": "expo publish",
"eject": "expo eject",
"optimize": "expo optimize"
},
"dependencies": {
"@expo/react-native-action-sheet": "^2.1.0",
"ex-react-native-i18n": "^0.0.6",
"expo": "^34.0.4",
"expo-file-system": "~6.0.0",
"expo-font": "~6.0.1",
"expo-keep-awake": "~6.0.0",
"expo-localization": "~6.0.0",
"expo-web-browser": "~6.0.0",
"hoist-non-react-statics": "^3.3.0",
"i18next": "^17.0.6",
"lodash": "^4.17.11",
"mobx": "5.11.0",
"mobx-react": "5.4.4 ",
"mobx-remotedev": "^0.3.6",
"moment": "^2.24.0",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-i18next": "^10.11.4",
"react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",
"react-native-datepicker": "^1.7.2",
"react-native-extended-stylesheet": "^0.12.0",
"react-native-gesture-handler": "~1.3.0",
"react-native-modal-popover": "^0.0.12",
"react-native-popover-view": "^2.0.2",
"react-native-popup-menu": "^0.15.6",
"react-native-reanimated": "~1.1.0",
"react-native-web": "^0.11.4",
"react-navigation": "^3.11.1"
},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-flow-strip-types": "^7.4.4",
"@babel/preset-env": "^7.5.5",
"@babel/preset-typescript": "^7.3.3",
"@types/enzyme": "^3.10.3",
"@types/enzyme-adapter-react-16": "^1.0.5",
"@types/expo": "^32.0.13",
"@types/jest": "^24.0.15",
"@types/node": "^12.6.8",
"@types/react": "^16.8.19",
"@types/react-native": "^0.57.60",
"@types/react-test-renderer": "^16.8.3",
"babel": "^6.23.0",
"babel-jest": "^24.8.0",
"babel-plugin-module-resolver": "^3.2.0",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-plugin-transform-exponentiation-operator": "^6.24.1",
"babel-plugin-transform-export-extensions": "^6.22.0",
"babel-preset-expo": "^5.1.1",
"babel-preset-react-native": "^4.0.1",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.3.5",
"expo-cli": "^3.0.2",
"jest": "^24.8.0",
"jest-enzyme": "^7.0.2",
"jest-expo": "^34.0.0",
"jest-fetch-mock": "^2.1.2",
"jest-junit": "^6.4.0",
"metro-react-native-babel-preset": "^0.55.0",
"react-dom": "^16.8.6",
"ts-jest": "^24.0.2",
"tslint": "^5.18.0",
"tslint-config-prettier": "^1.18.0",
"tslint-eslint-rules": "^5.4.0",
"tslint-react": "^4.0.0",
"typescript": "^3.4.5"
},
"private": true
}
预期结果是,测试将正确解决expo-localization和expo-vector-icons中的导入问题,并且不会引发Unexpected identifier
错误。