Open therynamo opened 2 years ago
What's your input file?
What's your input file?
Sorry, I don't understand. I'm just running yarn jest
. Are you asking what the test file itself looks like?
Yes. It's a parsing error so I need a repro case.
@kdy1 - I just put this together and was able to repro pretty quickly - https://github.com/therynamo/SWCJestRepro
@therynamo I checked it but it does not have a file named components/__tests__/EditScreenInfo.test.tsx
@kdy1 - so sorry about that π€¦ - I forgot to commit my changes π
. Try pulling from master
again now.
It does not have the required file, namely MyApp/x/y/z.spec.tsx
FAIL MyApp/x/y/z.spec.tsx
β Test suite failed to run
error: Expected ',', got ':'
|
51 | applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
| ^
Caused by:
0: failed to process js file
1: Syntax Error
at Compiler.transformSync (node_modules/@swc/core/index.js:137:25)
at transformSync (node_modules/@swc/core/index.js:217:21)
at Object.process (node_modules/@swc/jest/index.js:55:45)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:612:31)
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:758:40)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:815:19)
@kdy1 - yeah - that file was just an example file name. The edit screen info test in the repo I just linked causes the same error.
Were you able to pull down those updates I just pushed?
Here is a link to the new file https://github.com/therynamo/SWCJestRepro/blob/master/components/__tests__/EditScreenInfo.test.tsx
This test fails with the same error message.
applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
I need the file containing this line
Also, I don't pull files using my dev machines because it's a risk.
Yeah - that's the thing - there is no file containing that line. Which is the confusing part - the stack trace just indicates that there was an issue with @swc/core
processing the file.
Also, I don't pull files using my dev machines because it's a risk.
It will likely help if you can run this code, I'm not sure how you'd be able to debug this without it.
This repo I linked above is one I just freshly created when you asked me for the input file
- you can create the same exact repo on your own if that is more helpful:
https://reactnative.dev/docs/typescript
What I did to create this repo:
yarn global add expo-cli
expo init SWCJestRepro
# choose the option that has "tabs with typescript" (picture below)
yarn add -D babel-plugin-module-resolver @types/jest @testing-library/react-native @swc/core @swc/jest
Reference picture:
Then create a jest.config.js
with the contents from above, linked in the issue description.
https://github.com/therynamo/SWCJestRepro/blob/431a25102e8a649da17d7a783a737f2c8b68583b/jest.config.js#L1-L42
Then add a babel.config.js
file https://github.com/therynamo/SWCJestRepro/blob/431a25102e8a649da17d7a783a737f2c8b68583b/babel.config.js#L1-L19
Then create this test file with these contents:
(Note: if you don't fork the repo - consider deleting the .js
test that is generated for the project by expo as it will just muddy the problem space and what we're trying to resolve here).
Alternatively - you can just fork the repo I made for us and for this issue. I understand that we have to be safe, especially when dealing with open source, but the repo I just created is about as bare bones as any React Native project can be. And I can't be sure that there isn't something going on with RN in this particular issue.
I'm very invested in finding a way to utilize @swc/jest
for our project - so hopefully this helps you reproduce the issue that I have outlined above.
Let me know if you need any more information - happy to help where I can.
I'm out for the night, but I wonder if it's something in @testing-library/react-native
. I'll check by writing a different test tomorrow.
Thanks again for looking into this!
Actually it looks related to the react native preset https://github.com/dosentmatter/babel-plugin-const-enum/issues/3
Oh, thanks! I'll extract the test case using github codespaces
It seems like a bug of @react-native/polyfills
It seems like a bug of @react-native/polyfills
Hmm yeah - types should not be in a js
file - good catch. I can try to look into that - and maybe put in a fix. Likely will just need to patch-package
it if that removes all problems.
I'm investigating removing the react-native
preset all together in the jest.config
as it is mostly conditionally adding babel transforms - which SWC aims to eliminate in this situation. Right now I'm fighting with jest
imports and getting everything to resolve correctly without Babel. I'll report back if there are any valuable findings.
EDIT: the latter effort was fruitless - ending in this error:
Can't resolve 'react/jsx-runtime' from `./components/EditScreenInfo'
Alright - so after I "patch" the node_modules/@react-native/polyfills/error-guard.js
file to look like so:
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict
* @polyfill
*/
let _inGuard = 0;
/**
* This is the error handler that is called when we encounter an exception
* when loading a module. This will report any errors encountered before
* ExceptionsManager is configured.
*/
let _globalHandler = function onError(
e,
isFatal,
) {
throw e;
};
/**
* The particular require runtime that we are using looks for a global
* `ErrorUtils` object and if it exists, then it requires modules with the
* error handler specified via ErrorUtils.setGlobalHandler by calling the
* require function with applyWithGuard. Since the require module is loaded
* before any of the modules, this ErrorUtils must be defined (and the handler
* set) globally before requiring anything.
*/
const ErrorUtils = {
setGlobalHandler(fun) {
_globalHandler = fun;
},
getGlobalHandler() {
return _globalHandler;
},
reportError(error) {
_globalHandler && _globalHandler(error, false);
},
reportFatalError(error) {
// NOTE: This has an untyped call site in Metro.
_globalHandler && _globalHandler(error, true);
},
applyWithGuard(
fun,
context,
args,
// Unused, but some code synced from www sets it to null.
unused_onError,
// Some callers pass a name here, which we ignore.
unused_name,
){
try {
_inGuard++;
/* $FlowFixMe[incompatible-call] : TODO T48204745 (1) apply(context,
* null) is fine. (2) array -> rest array should work */
/* $FlowFixMe[incompatible-type] : TODO T48204745 (1) apply(context,
* null) is fine. (2) array -> rest array should work */
return fun.apply(context, args);
} catch (e) {
ErrorUtils.reportError(e);
} finally {
_inGuard--;
}
return null;
},
applyWithGuardIfNeeded(
fun,
context,
args,
) {
if (ErrorUtils.inGuard()) {
/* $FlowFixMe[incompatible-call] : TODO T48204745 (1) apply(context,
* null) is fine. (2) array -> rest array should work */
/* $FlowFixMe[incompatible-type] : TODO T48204745 (1) apply(context,
* null) is fine. (2) array -> rest array should work */
return fun.apply(context, args);
} else {
ErrorUtils.applyWithGuard(fun, context, args);
}
return null;
},
inGuard() {
return !!_inGuard;
},
guard(
fun,
name,
context,
) {
// TODO: (moti) T48204753 Make sure this warning is never hit and remove it - types
// should be sufficient.
if (typeof fun !== 'function') {
console.warn('A function must be passed to ErrorUtils.guard, got ', fun);
return null;
}
const guardName = name ?? fun.name ?? '<generated guard>';
function guarded(...args) {
return ErrorUtils.applyWithGuard(
fun,
context ?? this,
args,
null,
guardName,
);
}
return guarded;
},
};
global.ErrorUtils = ErrorUtils;
I now get this error from @swc/core
:
RUNS components/__tests__/EditScreenInfo.test.tsx
thread '<unnamed>' panicked at 'internal error: entered unreachable code: invalid pattern: Expr(Member(MemberExpr { span: Span { lo: BytePos(982), hi: BytePos(999), ctxt: #0 }, obj: Ident(Ident { span: Span { lo: BytePos(982), hi: BytePos(988), ctxt: #0 }, sym: Atom('global' type=static), optional: false }), prop: Ident(Ident { span: Span { lo: BytePos(989), hi: BytePos(999), ctxt: #0 }, sym: Atom('ErrorUtils' FAIL components/__tests__/EditScreenInfo.test.tsxecma_parser/src/parser/expr.rs:1700:44
β Test suite failed to run
failed to handle: internal error: entered unreachable code: invalid pattern: Expr(Member(MemberExpr { span: Span { lo: BytePos(982), hi: BytePos(999), ctxt: #0 }, obj: Ident(Ident { span: Span { lo: BytePos(982), hi: BytePos(988), ctxt: #0 }, sym: Atom('global' type=static), optional: false }), prop: Ident(Ident { span: Span { lo: BytePos(989), hi: BytePos(999), ctxt: #0 }, sym: Atom('ErrorUtils' type=dynamic), optional: false }) }))
at Compiler.transformSync (node_modules/@swc/core/index.js:137:25)
at transformSync (node_modules/@swc/core/index.js:217:21)
at Object.process (node_modules/@swc/jest/index.js:55:45)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:619:31)
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:765:40)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:822:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.106 s
Ran all test suites.
You should be able to copy paste the fixed file without any types into whatever env you were using to reproduce this error.
Also - I've filed a bug with the RN
team to see if this is intended or not https://github.com/facebook/react-native/issues/33426
Just a heads up that I'm having the same issue.
EDIT: The correct error (after setting up the config)
β Test suite failed to run
Γ Expected ',', got ':'
βββββ
51 β applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
Β· β
β°ββββ
Caused by:
0: failed to process input file
1: Syntax Error
at Compiler.transformSync (../../node_modules/@swc/core/index.js:137:25)
at transformSync (../../node_modules/@swc/core/index.js:217:21)
at Object.process (../../node_modules/@swc/jest/index.js:55:45)
@coelhucas It's an issue of your config
I see there's no good solution for this so I thought I should share what I did to work around this issue.
Since some of the file provided by the react-native libraries, for some ungodly reason have a .js
extension but actually include TypeScript code, SWC is unable to process those files correctly, however babel can somehow make it work, so I've set jest transform patterns to use babel for any .js
files from react-native libraries, while all other code is using SWC. Here's how jest transforms look like:
module.exports = {
transform: {
'^.+/((@)?react-native)/.+\\.(js|jsx)$': 'babel-jest',
'^.+\\.(js|ts|jsx|tsx)$': '@swc/jest',
}
}
I don't think this is a good solution, but it works and I've managed to achieve what I wanted (much faster test runs).
I see there's no good solution for this so I thought I should share what I did to work around this issue.
Since some of the file provided by the react-native libraries, for some ungodly reason have a
.js
extension but actually include TypeScript code, SWC is unable to process those files correctly, however babel can somehow make it work, so I've set jest transform patterns to use babel for any.js
files from react-native libraries, while all other code is using SWC. Here's how jest transforms look like:module.exports = { transform: { '^.+/((@)?react-native)/.+\\.(js|jsx)$': 'babel-jest', '^.+\\.(js|ts|jsx|tsx)$': '@swc/jest', } }
I don't think this is a good solution, but it works and I've managed to achieve what I wanted (much faster test runs).
It isn't actually typescript but rather flow and this is why even if the typescript parser is used for everything it fails. btw thanks for the solution
Hello guys, I'm facing the same issue. I add this and the same error ocrrur. Can some one help me?
module.exports = {
transform: {
'^.+/((@)?react-native)/.+\\.(js|jsx)$': 'babel-jest',
'^.+\\.(js|ts|jsx|tsx)$': '@swc/jest',
}
}
here is my repository https://github.com/lucaslozz/imhere.git
@lucaslozz Maybe it's transformIgnorePatterns
, try leaving the array empty. In my case it worked.
@camilossantos2809 I try it and nothing changed.is There someway to ignore those files?
@lucaslozz can you show the exact error you are getting?
@ncpa0cpl it's the same error of the issue
` Test suite failed to run
Γ Expected ';', '}' or <eof>
ββ[D:\GIT\imhere\node_modules\@react-native\polyfills\error-guard.js:11:1]
11 β
12 β let _inGuard = 0;
13 β
14 β type ErrorHandler = (error: mixed, isFatal: boolean) => void;
Β· βββ¬β ββββββββββββ
Β· β°ββ This is the expression part of an expression statement
15 β type Fn<Args, Return> = (...Args) => Return;
16 β
17 β /**
β°ββββ
Caused by:
Syntax Error
at Compiler.transformSync (node_modules/@swc/core/index.js:241:29)
at transformSync (node_modules/@swc/core/index.js:348:21)
at Object.process (node_modules/@swc/jest/index.js:73:45)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:542:31)
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:671:40)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:723:19)`
So the file on which it fails for you (D:\GIT\imhere\node_modules\@react-native\polyfills\error-guard.js
) is being transformed using swc instead of babel, that's why it fails. The regex I've given in my first post here should match this file import so I am unsure why is Jest using swc instead of babel for that file.
The only thing I can think of is that the actual file path is used to match against the regex rather than the import path, in which case the regex I've posted would not work on Windows, since Windows uses backslashes in filepaths and the regex was written for Unix systems that use regular slashes.
This is just a guess tho, and I am unable to verify that since I do not have access to any Windows machine. You can try replacing the slashes to backslashes in that regex and see if anything changes.
@camilossantos2809 I've tried and now it's working. Thanks for help me!
For me this extra transform helped:
transform: {
'^.+/((@)?react-native)/.+\\.(js|jsx)$': 'babel-jest',
'^.+\\.(t|j)sx?$': '@swc/jest',
},
It then compiles react-native flow files with babel-jest, and my own files with swc. On a vanilla React Native project created with their template, the result is actually slightly slower.
Overall it looks like a better solution would be removing flow types before publishing the react-native npm packages: https://github.com/facebook/react-native/issues/33426#issuecomment-1786760207
@jzaefferer I wish you luck in convincing the facebook team to add a build step that will be necessary for this to RN project, I'd love to see them do that, it would help me a lot. In the project I am working on we have ~1.5k unit tests and it takes forever to complete, I will take anything that could speed it up by even a few percent.
I have come to
@swc/jest
because of the recentts-jest
issues https://github.com/kulshekhar/ts-jest/issues/1967 (Granted it could beJest
it could bev8
. Ultimately - I just wanted to move to SWC to get faster, more stable, and ultimately the most performant tests I can run).I am trying to use this package with a React Native app - and am running into issues after I resolve the one listed here. I have tried a couple of different
.swcrc
configurations:And just a basic one from the example in the repo here: https://github.com/swc-project/jest/blob/466035925e289e6a6cc747ff7939a63c8a94c7a2/examples/react/package.json#L33-L51
The above works without a physical
.swcrc
file - which is what I'll opt for since our App wont be built using SWC yet (or maybe ever π€· Depends on the RN support in the future.)The issue I'm running into now - is very similar:
I haven't had any luck getting past this point and would LOVE some help troubleshooting how to move forward.
My current
jest.config.js
tsconfig.json
babel.config.js