facebookexperimental / Recoil

Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.
https://recoiljs.org/
MIT License
19.57k stars 1.18k forks source link

[React Native] react-dom error on nightly build #755

Open watanabeyu opened 3 years ago

watanabeyu commented 3 years ago

Hi there. I use recoil#nightly on react-native. It was not problem until now, but new version came out has a react-dom problem. May be below is affected.

https://github.com/facebookexperimental/Recoil/blob/nightly/native/recoil.js#L1

wojtekmaj commented 3 years ago

That sounds like too little info to help you; care to paste the entire error w. stack?

drarmstr commented 3 years ago

@watanabeyu Can you please clarify what the error is or if it is still an issue?

mheiber commented 3 years ago

I'm getting this error in tests when using Jest with recoil 0.1.2:

    Cannot find module 'react-dom' from 'recoil.js'

    Require stack:
      node_modules/recoil/cjs/recoil.js
      src/state.test.tsx

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:299:11)
      at Object.<anonymous> (node_modules/recoil/cjs/recoil.js:7:32)
drarmstr commented 3 years ago

@mheiber Does some dependency need to be updated?

eomttt commented 3 years ago

@drarmstr i have same problem with @mheiber

juho-ylikyla commented 3 years ago

Jest can't figure out that it should use the react-native specific version of recoil.js

I used this hack in a jest setup script to resolve the issue

jest.doMock('recoil', () => require('recoil/native/recoil'));

NehrDani commented 3 years ago

I too still have this issue with 0.2.0. The fix @juho-ylikyla mentioned doesn't work and just throws another error:

 FAIL  src/utils/__tests__/auth.test.ts
  ● 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:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • 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:

    /home/daniel/Projects/sc-app/node_modules/recoil/native/recoil.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import reactNative from 'react-native';
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      1 | /* global jest */
      2 |
    > 3 | jest.doMock('recoil', () => require('recoil/native/recoil'))
        |                             ^
      4 | jest.mock('@react-native-async-storage/async-storage', () =>
      5 |   require('@react-native-async-storage/async-storage/jest/async-storage-mock'),
      6 | )

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at config/jest/jest.setup.js:3:29
      at Object.<anonymous> (src/utils/auth.ts:2:1)
juho-ylikyla commented 3 years ago

I think you need to add recoil to jest transformIgnorePatterns

Example: "transformIgnorePatterns": [ "node_modules/(?!((jest-)?react-native|@react-navigation|recoil))" ],

NehrDani commented 3 years ago

@juho-ylikyla thank you for your fast answer, but sadly this only results in just another Error:

FAIL  __tests__/App-test.tsx
  ● Test suite failed to run

    /home/daniel/Projects/sc-app/node_modules/@react-native/polyfills/error-guard.js:14
    type ErrorHandler = (error: mixed, isFatal: boolean) => void;
         ^^^^^^^^^^^^

    SyntaxError: Unexpected identifier

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (node_modules/react-native/jest/setup.js:439:6)
juho-ylikyla commented 3 years ago

The transformIgnorePatterns I mentioned was just an example and you might need something a bit different. Check out this StackOverflow discussion https://stackoverflow.com/questions/60021119/how-can-i-stop-my-react-native-tests-bombing-out-on-flow-types-in-node-modules

NehrDani commented 3 years ago

@juho-ylikyla thank you for that link. Should have searched for it by myself (shame on me) :pensive:. But now it works. I added @react-native and react-native to transformIngorePatterns: package.json:

{
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/(?!(@react-native|react-native|recoil)/)"
    ],
    "setupFiles": [
      "<rootDir>/config/jest/jest.setup.js"
    ]
}

jest.setup.js:

jest.doMock('recoil', () => require('recoil/native/recoil'))

As additional info: I'm using a normal React Native project initialized with react-native-cli and the typescript template.

I wonder if this is an issue with recoil or jest or even react-native.

numandev1 commented 2 years ago

just installed react-dom and the error is resolved 😄

henninghall commented 2 years ago

Solved it by changing jest.config.js to this:

transformIgnorePatterns: [
-  'node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|rollbar-react-native|@fortawesome|@react-native|@react-navigation)'
+  'node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|rollbar-react-native|@fortawesome|@react-native|@react-navigation|recoil)'
],
moduleNameMapper: {
+  recoil: 'recoil/native'
}