SyntaxError: Unexpected token import
Jest throw an error when he try to parse React Navigation package who has ES2015 imports.
Following dedicated React Native documentation and ES2015 documentation I expect that .js files under node_modules to be processed by babel-jest.
module.exports = {
preset: "react-native",
transform: {
"^.+\\.jsx?$": "<rootDir>/node_modules/babel-jest",
"^.+\\.tsx?$": "ts-jest"
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
globals: {
"ts-jest": {
useBabelrc: true
}
}
};
{
"presets": ["react-native"],
"sourceMaps": "inline"
}
/Users/nicolas/Projects/react-native-typescript/node_modules/react-navigation/src/navigators/createStackNavigator.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React from 'react';
^^^^^^
You can find an example with a simple test.
Thanks !
I am having the same issue. Started happening when I tried to upgrade to RN 0.56
What version of Babel are you using? Babel 7 now handles .babelrc files different (i.e. doesn't handle them). See facebook/jest#6229. This means that the instructions for setting up ts-jest with React Native and Babel 7 do not work. The workaround to change .babelrc to babel.config.js doesn't work for me.
Also see my comment in facebook/jest#6229
@huafu, @kulshekhar this is blocking me use ts-jest ^23 with any of our React Native projects. I'm happy to investigate this if you can point me in the right direction?
You can reproduce it on ef-carbon/react-native-async-button.
Upgrading ts-jest to ^23 results in the following error when yarn test is ran:
FAIL test/ContextAsyncButton.test.tsx
● Test suite failed to run
TypeError: Cannot read property 'bindings' of null
at Scope.moveBindingTo (node_modules/@babel/core/node_modules/@babel/t
raverse/lib/scope/index.js:869:13)
at BlockScoping.updateScopeInfo (node_modules/babel-plugin-transform-e
s2015-block-scoping/lib/index.js:364:17)
at BlockScoping.run (node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:330:12)
at PluginPass.BlockStatementSwitchStatementProgram (node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:70:24)
at newFn (node_modules/@babel/core/node_modules/@babel/traverse/lib/visitors.js:193:21)
at NodePath._call (node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:53:20)
at NodePath.call (node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:40:17)
at NodePath.visit (node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:88:12)
at TraversalContext.visitQueue (node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:118:16)
at TraversalContext.visitSingle (node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:90:19)
I assume this is because something in ts-jest is loading Babel 7, but something else expects Babel 6. If I upgrade babel-core to 7.0.0-bridge.0. Still get the same error, so upgrade babel-preset-react-native. I then start getting the SyntaxError as stated:
FAIL test/ContextAsyncButton.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 canno
t 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:
SyntaxError: /Users/mattyclarkson/git/github/ef-carbon/react-native-async-button/node_modules/react-native/Libraries/StyleSheet/StyleSheet.js: Unexpected token (18:12)
16 | const flatten = require('flattenStyle');
17 |
> 18 | import type {
| ^
19 | ____Styles_Internal,
20 | ____DangerouslyImpreciseStyle_Internal,
21 | ____DangerouslyImpreciseStyleProp_Internal,
at Parser.raise (node_modules/@babel/core/node_modules/babylon/lib/index.js:776:15)
at Parser.unexpected (node_modules/@babel/core/node_modules/babylon/lib/index.js:2079:16)
at Parser.expectContextual (node_modules/@babel/core/node_modules/babylon/lib/index.js:2047:41)
at Parser.parseImport (node_modules/@babel/core/node_modules/babylon/lib/index.js:5205:12)
at Parser.parseStatementContent (node_modules/@babel/core/node_modules/babylon/lib/index.js:4043:27)
at Parser.parseStatement (node_modules/@babel/core/node_modules/babylon/lib/index.js:3962:17)
at Parser.parseBlockOrModuleBlockBody (node_modules/@babel/core/node_modules/babylon/lib/index.js:4513:23)
at Parser.parseBlockBody (node_modules/@babel/core/node_modules/babylon/lib/index.js:4500:10)
at Parser.parseTopLevel (node_modules/@babel/core/node_modules/babylon/lib/index.js:3938:10)
at Parser.parse (node_modules/@babel/core/node_modules/babylon/lib/index.js:5304:17)
So I then add the following to the jest configuration:
"transformIgnorePatterns": [
"/node_modules/(?!react-native).+\\.js$"
],
Still get the same error. I've tried all kinds of different transform patterns and other fruitless investigation.
Not sure if this is a problem with ts-jest anymore or it's a result of babel-preset-react-native. Or if I should be using babel-preset-env instead.
Thank @mattyclarkson for the investigation. Here is some quick info I can give you know:
First of all, when you try something else, be sure to run jest --clearCache to ensure jest will run with the new settings/packages. I've reported the bug in jest, jest --no-cache does use some of the cache so it's safer to jest --clearCache.
For babel, if you install babel 7, ts-jest will use it. Else it'll use the 6.
For the repository link you gave, it's pointing to a no more existing hash. If the issue is in the master of this repo as well, lemme know and I'll try to investigate when I'll have a bit more time.
Ooo, thanks for the tip. That helps.
I've updated the link in the above comment, it was suppose to just point at master, sorry about that 🤦♂️ . It's also here for convienence.
I wrote step by step what I did, maybe it could help you investigate later some other bugs:
babel-core, @babel/core and babel-jest to be sure jest will use the defaults sipped with it. ts-jest (it was 22).yarn why @babel/core to see if it was still installed, and if so why. Turns out babel 7 WILL be chosen and installed because of react-native (@babel/core => metro => react-native).babel-plugin-transform-es2015-block-scoping. It's trying to move a let to parent scope which apparently doesn't exist.es2015+ to es5, so I changed the target in test/tsconfig.json to es5, so that this part of the process would be done by TypeScript and not babel. It's weird, but it sounds like a babel 7 bug, or maybe a bug due to the combination of some babel plugins.babel-plugin-transform-es2015-block-scoping in babel issues and boom https://github.com/babel/babel/issues/7627#issuecomment-409776114.babelrc which is bringing some v6 plugins? oh react-native[email protected] and @babel/core (yes, back in for this last one, I shouldn't have removed it...)babel-jest now, ok I shouldn't have removed that one tooJest encountered an unexpected token!js
transformIgnorePatterns: [
"<rootDir>/node_modules/react-native/.+"
]
flow in there node_modules/react-native/Libraries/StyleSheet/StyleSheet.jsyarn add --dev @babel/preset-flowpresets array of .babelrc to prepend with @babel/preset-flowMy time on this is over sorry, I'll let you follow here, maybe tomorrow or another day if you still stuck I'll continue to drop an eye, I hope these last few steps will help you
Oh @mattyclarkson look at this https://github.com/facebook/react-native/issues/19859#issuecomment-402621849
Also something to note: removing all node_modules and re-running yarn is sometimes good thing to do after messing up with multiple yarn add ... and yarn remove ...
Ahhhhh I must be too tired, going back to my project I realized I made a mistake in the ignore pattern...
- added the right regexp to jest config:
no, it was wrong! So I fixed it:
transformIgnorePatterns: [
"/node_modules/(?!react-native)/.+"
]
...because yeah, we want ti to NOT ignore processing the react-native's files
Now it complains about some React thing, so there you go that's not for me :-D
console.error node_modules/fbjs/lib/warning.js:33
Warning: AsyncButton(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.
console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6309
The above error occurred in the <AsyncButton> component:
in AsyncButton
...
@mattyclarkson if you find out it's related to ts-jest, please re-open this issue.
For others landing here, you might be interested in:
https://github.com/babel/babel/issues/7627#issuecomment-409776114 and https://github.com/facebook/react-native/issues/19859#issuecomment-402621849
Finally works fine!
Jest config in package.json:
{
"devDependencies": {
"babel-jest": "^23.6.0",
"jest": "^23.6.0",
"ts-jest": "^23.1.4",
"typescript": "^3.2.1"
...
},
"jest": {
preset: "react-native",
transform: {
"^.+\\.jsx?$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
"^.+\\.tsx?$": "ts-jest"
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
globals: {
"ts-jest": {
"tsConfigFile": "tsconfig.jest.json"
}
}
}
...
}
TS config in tsconfig.json:
{
"compilerOptions": {
// https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/
"target": "esnext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"noImplicitAny": true,
"allowSyntheticDefaultImports": true,
"jsx": "react-native",
"lib": [
"esnext"
],
"types": [ // fix declaration collision between react-native and ts-jest
"react",
"react-native",
"react-redux",
"redux"
...
]
},
"include": [
"src"
]
}
TS config in tsconfig.jest.json:
{
"extends": "./tsconfig",
"compilerOptions": {
"jsx": "react",
"module": "commonjs"
}
}
Babel config in .babelrc:
{
"presets": [
"module:metro-react-native-babel-preset"
],
"env": {
"test": {
"presets": [
"react-native",
[
"@babel/preset-env"
]
]
}
}
}
Thanks 🙏
Most helpful comment
Ahhhhh I must be too tired, going back to my project I realized I made a mistake in the ignore pattern...
no, it was wrong! So I fixed it:
...because yeah, we want ti to NOT ignore processing the
react-native's filesNow it complains about some React thing, so there you go that's not for me :-D
@mattyclarkson if you find out it's related to ts-jest, please re-open this issue.
For others landing here, you might be interested in:
https://github.com/babel/babel/issues/7627#issuecomment-409776114 and https://github.com/facebook/react-native/issues/19859#issuecomment-402621849