teambit / envs

Component development environments for the Bit community
https://bit.dev/bit/envs
Other
64 stars 9 forks source link

Expo "jest-haste-map" error after bit import of any component #149

Closed jimmi-joensson closed 4 years ago

jimmi-joensson commented 4 years ago

Describe the bug

I'm experiencing a jest-haste-map error after bit importing any component into a new initialised Expo Managed Workflow project. I have tried to exclude the bit directory with modulePathIgnorePatterns in jest.config.js without success.

module.exports = {
  modulePathIgnorePatterns: ['<rootDir>/bit/']
};

I also tried to exclude by blacklisting it in metro.config.js as suggested here.

const blacklist = require('metro-config/src/defaults/blacklist');

// blacklist is a function that takes an array of regexes and combines
// them with the default blacklist to return a single regex.

module.exports = {
  resolver: {
    blacklistRE: blacklist([/bit\/.*/])
  }
};

however this resulted in the app not being able to locate the component at all.

Failed building JavaScript bundle.
Unable to resolve "@bit/jimmijoensson.keyhole.paragraph" from "App.tsx"

Steps to Reproduce

  1. expo init expo-test/
  2. Choose "blank (Typescript)" Managed workflow
  3. cd ./expo-test/
  4. setup package.json with bit settings
  5. bit init
  6. npm install <any-typescript-bit-component> and implement this component in App.tsx
  7. npm run ios - Everything runs great
  8. Stop the build again with ctrl+c
  9. bit import <any-typescript-bit-component>
  10. npm run ios and the "jest-haste-map" error occur.
  11. bit eject <any-typescript-bit-component> and everything works again

Expected Behavior

The expectation is no jest-haste-map error

Screenshots, exceptions and logs

"jest-haste-map" error:

jest-haste-map: Haste module naming collision: @bit/jimmijoensson.keyhole.paragraph
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>/bit/paragraph/dist/package.json
    * <rootDir>/bit/paragraph/package.json

Failed to construct transformer:  DuplicateError: Duplicated files or mocks. Please check the console for more info
    at setModule (/Users/jimmijonsson/Repositories/expo-test/node_modules/jest-haste-map/build/index.js:620:17)
    at workerReply (/Users/jimmijonsson/Repositories/expo-test/node_modules/jest-haste-map/build/index.js:691:9)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Promise.all (index 10) {
  mockPath1: 'bit/paragraph/dist/package.json',
  mockPath2: 'bit/paragraph/package.json'
}

This error makes it impossible to work locally on a bit component and test it in an IOS simulator. The following errors are shown when the simulator loads:

IOS simulator error:

Could not connect to development server.

Ensure the following:
- Node server is running and available on the same network - run 'npm start' from react-native root
- Node server URL is correctly set in AppDelegate
- WiFi is enabled and connected to the same network as the Node Server

URL: http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false

ABI38_0_0RCTFatal
__37-[ABI38_0_0RCTCxxBridge handleError:]_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
UIApplicationMain
main
start
0x0

Console error:

Error: Duplicated files or mocks. Please check the console for more info
    at setModule (/Users/jimmijonsson/Repositories/expo-test/node_modules/jest-haste-map/build/index.js:620:17)
    at workerReply (/Users/jimmijonsson/Repositories/expo-test/node_modules/jest-haste-map/build/index.js:691:9)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Promise.all (index 10)

Specifications

Additional context

package.json with Bit settings

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "expo": "~38.0.8",
    "expo-status-bar": "^1.0.2",
    "react": "~16.11.0",
    "react-dom": "~16.11.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.1.tar.gz",
    "react-native-web": "~0.11.7",
    "styled-components": "^5.1.1",
    "expo-font": "~8.2.1",
    "@bit/jimmijoensson.keyhole.paragraph": "0.0.6"
  },
  "devDependencies": {
    "@babel/core": "^7.8.6",
    "@types/react": "~16.9.41",
    "@types/react-native": "~0.62.13",
    "@types/styled-components": "^5.1.0",
    "typescript": "~3.9.5"
  },
  "private": true,
  "bit": {
    "env": {
      "compiler": "bit.envs/compilers/typescript@3.0.35"
    },
    "componentsDefaultDirectory": "bit/{name}",
    "packageManager": "npm",
    "defaultScope": "jimmijoensson.keyhole",
    "overrides": {
      "jimmijoensson.keyhole/router-native-web": {
        "dependencies": {
          "react-router-native": "-",
          "react-router-dom": "-"
        },
        "devDependencies": {
          "@types/react-router-native": "-",
          "@types/react-router-dom": "-"
        },
        "peerDependencies": {
          "react-router-native": "+",
          "react-router-dom": "+",
          "@types/react-router-native": "+",
          "@types/react-router-dom": "+"
        }
      },
      "*": {
        "dependencies": {
          "@types/react": "-",
          "@types/react-native": "-",
          "@types/styled-components": "-",
          "react": "-",
          "react-native": "-",
          "styled-components": "-"
        },
        "devDependencies": {
          "@types/react": "-",
          "@types/react-native": "-",
          "@types/styled-components": "-",
          "react": "-",
          "react-native": "-",
          "styled-components": "-"
        },
        "peerDependencies": {
          "@types/react": "+",
          "@types/react-native": "+",
          "@types/styled-components": "+",
          "react": "+",
          "react-native": "+",
          "styled-components": "+"
        }
      }
    }
  }
}
jimmi-joensson commented 4 years ago

I have found a solution to the issue. Using this regex /\/bit\/(?!.*dist).*/ all the non 'dist' files from my imported component are blacklisted from the project.

metro.config.js

const blacklist = require('metro-config/src/defaults/blacklist');

// blacklist is a function that takes an array of regexes and combines
// them with the default blacklist to return a single regex.

module.exports = {
  resolver: {
    blacklistRE: blacklist([/\/bit\/(?!.*dist).*/])
  }
};

I will let you decide if this is an acceptable solution for the issue. I think it is if the solution is added in a guide or the docs.

Best regards!

JoshK2 commented 4 years ago

Hi @jimmi-joensson,

First, thanks for opening the issue and documenting well the problem. Thanks for your solution, I already wrote about it in another issue with another error but with the same solution, maybe the regex needs to be adjusting depending on the error we get. I also wrote about it in the compiler page in bit.dev.

I close the issue, and I'll also something about this issue in the compiler README. Thanks!

jimmi-joensson commented 4 years ago

@JoshK2 You're welcome!

No problem, it was the least I could do. Its good that it is described at the compiler page. However, I think it might be a bit miss-placed there. When I was looking for a solution to my issue, I was looking first at the docs and more preciously the guides. I think it would be great to have a RN section under "Frameworks" in the submenu and include it there. It never occurred to me that the answer could be under the RN or for that matter any compiler page.

JoshK2 commented 4 years ago

You completely right about it, I'll add soon as possible documentation about RN and about the possible issues users can have.