単純なインポート文でJest
が「予期しないトークン*」で失敗するのはなぜですか...
Admin@Admin-PC MINGW32 /d/project (master)
$ npm run test
> [email protected] test D:\project
> jest
FAIL __tests__/App-test.tsx
? Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
D:\project\node_modules\react-navigation-tabs\src\navigators\createBottomTabNavigator.js:3
import * as React from 'react';
^
SyntaxError: Unexpected token *
14 | // );
15 |
> 16 | export default createBottomTabNavigator({
| ^
17 | map: {
18 | screen: MapView,
19 | navigationOptions: {
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.get createBottomTabNavigator [as createBottomTabNavigator] (node_modules/react-navigation-tabs/src/index.js:9:12)
at Object.<anonymous> (src/app/main.view.tsx:16:16)
FAIL src/component/reinput/example/__tests__/index.ios.js (19.352s)
? Console
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:59
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
? renders correctly
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at invariant (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:55:15)
at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2054:11)
at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2075:15)
at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4605:23)
at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4662:35)
at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6329:28)
at updateHostRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6741:5)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7566:14)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11234:12)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11266:24)
FAIL src/component/reinput/example/__tests__/index.Android.js (19.365s)
? Console
console.error node_modules/react-native/Libraries/YellowBox/YellowBox.js:59
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
? renders correctly
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at invariant (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:55:15)
at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2054:11)
at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2075:15)
at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4605:23)
at reconcileChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4662:35)
at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6329:28)
at updateHostRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6741:5)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7566:14)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11234:12)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11266:24)
Test Suites: 3 failed, 3 total
Tests: 2 failed, 2 total
Snapshots: 0 total
Time: 22.774s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test: `jest`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Admin\AppData\Roaming\Roaming\npm-cache\_logs\2019-04-22T11_52_36_984Z-debug.log
package.json
ファイル:{
"name": "MyApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.4",
"react-native-gesture-handler": "^1.1.0",
"react-native-reanimated": "^1.0.1",
"react-native-splash-screen": "^3.2.0",
"react-navigation": "^3.8.1",
"react-navigation-tabs": "^2.1.1"
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/runtime": "^7.4.3",
"@types/jest": "^24.0.11",
"@types/react": "^16.8.13",
"@types/react-dom": "^16.8.4",
"@types/react-native": "^0.57.46",
"@types/react-test-renderer": "^16.8.1",
"babel-jest": "^24.7.1",
"jest": "^24.7.1",
"metro-react-native-babel-preset": "^0.53.1",
"react-test-renderer": "16.8.3",
"TypeScript": "^3.4.3"
},
"jest": {
"preset": "react-native"
}
}
babel.config.js
ファイル:module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
jest.config.js
ファイル:module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
}
注:私はreact-native
のようなreact-native init MyApp --template TypeScript
タイプスクリプトテンプレートを使用しています
一部のreact-native
ライブラリには、コンパイルされていないES6コードが付属しています。
ES6コードは、Jest
で実行する前にコンパイルする必要があります。
テストに関するJest
ドキュメントには、React Native Apps に関するセクションが含まれています プリコンパイルされたコードを出荷しない依存関係のコンパイル 。
Jest
設定のtransformIgnorePatterns
オプションでホワイトリストに登録することにより、Jest
にreact-navigation-tabs
をコンパイルするように指示する必要があります。
jest.config.js
ファイルを以下のように変更すると、OPで言及されている問題が修正されました。
しかし、「react-native-reanimated
」モジュール( another post で説明されているように、ネイティブ統合が必要)にはさらに作業が必要であり、Mock
そのようなネイティブの要件を持つモジュール...
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
transformIgnorePatterns: [
"node_modules/(?!(react-native"
+ "|react-navigation-tabs"
+ "|react-native-splash-screen"
+ "|react-native-screens"
+ "|react-native-reanimated"
+ ")/)",
],
}
注:transformIgnorePatterns
オプション(正規表現の配列)は、元々ファイルをコンパイルから除外することを目的としていますが、(?!(some-dir-name|another-name))
パターン((?!...)
、ネガティブルックアヘッドを使用しています)、指定した名前を除き、Jest
にnode_modules
ディレクトリ内のすべてを除外するように指示します。
言われたように、いくつかのモジュールはトランスパイルする必要があります、そしていくつかはそうではありません。これは私が多くのプロジェクトで使用する正規表現です
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-(native|universal|navigation)-(.*)|@react-native-community/(.*)|@react-navigation/(.*)|bs-platform)"
]
}
それは最も一般的な反応ネイティブのもののために働いており、特定のパッケージも含みます(ここでbs-platform
)例として、以前のパターンでキャプチャされない場合。
設定ファイル(.babelrc.jsまたはpackage.json)のどこかに、「プリセット」の下の「モジュール」を「AMD」のいずれかに設定する必要があります。 「umd」| 「systemjs」| 「commonjs」| "cjs" | 「自動」| false。
参照元 このフラグメント ドキュメントから
このようなもの:
"presets": [
[
"@babel/preset-env", {
"targets": process.env.BABEL_TARGET === 'node' ? {
"node": 'current'
} : {
"browsers": [ "last 2 versions" ]
},
"loose": true,
"modules": 'commonjs'
}
]
]