software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
8.86k stars 1.29k forks source link

Unable to resolve path to module 'react-native-reanimated' eslintimport/no-unresolved #4244

Closed MajStc closed 1 year ago

MajStc commented 1 year ago

Description

First of all - reanimated works as expected with no runtime issues at all.

After installing react-native-reanimted my eslint/typescript checks became buggy (I had to restart the server after - as it turned out - each time I visited a file that included reanimated import). I quickly discovered uninstalling reanimated fixes the issue, also in the component where I use reanimated I see below errors

Unable to resolve path to module 'react-native-reanimated'.eslint[import/no-unresolved](https://github.com/import-js/eslint-plugin-import/blob/v2.27.5/docs/rules/no-unresolved.md)

and

Untitled

This is my package.json

{
  "name": "xxx",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint ./src/**/* --color",
    "start": "react-native start",
    "test": "jest",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook",
    "postinstall": "patch-package",
    "typescript": "tsc --project tsconfig.json --noEmit",
    "prettier": "prettier ./src/**/* -check",
    "lint-staged": "lint-staged --config lint-staged.js",
    "husky-install": "husky install"
  },
  "dependencies": {
    "@emotion/native": "^11.10.6",
    "@emotion/react": "^11.10.6",
    "@react-navigation/bottom-tabs": "^6.5.7",
    "@react-navigation/native": "^6.1.6",
    "@react-navigation/native-stack": "^6.9.12",
    "@shopify/flash-list": "^1.4.1",
    "axios": "^1.3.4",
    "patch-package": "^6.5.1",
    "postinstall-postinstall": "^2.1.0",
    "react": "18.2.0",
    "react-native": "0.71.4",
    "react-native-fast-image": "^8.6.3",
    "react-native-gesture-handler": "^2.9.0",
    "react-native-linear-gradient": "^2.6.2",
    "react-native-reanimated": "3.0.1",
    "react-native-safe-area-context": "^4.5.0",
    "react-native-screens": "^3.20.0",
    "react-native-svg": "^13.8.0",
    "react-native-svg-transformer": "^1.0.0",
    "react-native-web-linear-gradient": "^1.1.2",
    "react-query": "^3.39.3"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native-community/eslint-config": "^3.2.0",
    "@storybook/addon-actions": "^6.5.16",
    "@storybook/addon-essentials": "^6.5.16",
    "@storybook/addon-interactions": "^6.5.16",
    "@storybook/addon-links": "^6.5.16",
    "@storybook/addon-react-native-web": "^0.0.19",
    "@storybook/addon-styling": "^0.3.1",
    "@storybook/builder-webpack4": "^6.5.16",
    "@storybook/builder-webpack5": "^6.5.16",
    "@storybook/manager-webpack4": "^6.5.16",
    "@storybook/manager-webpack5": "^6.5.16",
    "@storybook/react": "^6.5.16",
    "@storybook/testing-library": "^0.0.13",
    "@svgr/webpack": "^6.5.1",
    "@tsconfig/react-native": "^2.0.2",
    "@types/jest": "^29.2.1",
    "@types/react": "^18.0.24",
    "@types/react-test-renderer": "^18.0.0",
    "@typescript-eslint/parser": "^5.55.0",
    "babel-jest": "^29.2.1",
    "babel-loader": "^8.3.0",
    "babel-plugin-module-resolver": "^5.0.0",
    "babel-plugin-react-native-web": "^0.18.12",
    "eslint": "^8.19.0",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-import-resolver-typescript": "^3.5.3",
    "eslint-plugin-import": "^2.27.5",
    "eslint-plugin-react-hooks": "^4.6.0",
    "husky": "^8.0.3",
    "jest": "^29.2.1",
    "lint-staged": "^13.2.0",
    "metro-react-native-babel-preset": "0.73.8",
    "prettier": "^2.4.1",
    "react-dom": "^18.2.0",
    "react-native-web": "^0.18.12",
    "react-test-renderer": "18.2.0",
    "tsconfig-paths-webpack-plugin": "^4.0.1",
    "typescript": "4.8.4"
  },
  "jest": {
    "preset": "react-native"
  }
}

My eslintrc.js

module.exports = {
  root: true,
  extends: [
    '@react-native-community',
    'prettier',
    'eslint:recommended',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/typescript',
  ],
  plugins: ['import', 'react-hooks'],
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx'],
    },
    'import/resolver': {
      alias: {
        map: [
          ['~navigation', './src/navigation'],
          ['~presentation', './src/presentation'],
          ['~ui', './src/ui'],
          ['~auth', './src/auth'],
          ['~assets', './src/assets'],
          ['~hooks', './src/hooks'],
          ['~api', './src/api'],
        ],
        extensions: ['.ts', '.tsx'],
      },
      typescript: {
        alwaysTryTypes: true,
        directory: './tsconfig.json',
      },
      node: {
        extensions: ['.js', '.jsx', '.json', '.native.js', '.ts', '.tsx', '.native.ts'],
      },
    },
  },
  rules: {
    'import/no-unresolved': 'error',
    'import/named': 2,
    'import/namespace': 2,
    'import/default': 2,
    'import/export': 2,
    'import/order': [
      'error',
      {
        'newlines-between': 'always',
      },
    ],
  },
  overrides: [
    {
      files: ['*.ts', '*tsx'],
      rules: {
        'no-undef': 0,
        'no-unused-vars': 0,
      },
    },
  ],
}

and my babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./'],
        alias: {
          '~navigation': './src/navigation',
          '~presentation': './src/presentation',
          '~ui': './src/ui',
          '~auth': './src/auth',
          '~assets': './src/assets',
          '~hooks': './src/hooks',
          '~api': './src/api',
        },
        extensions: ['.ios.js', '.android.js', '.js', '.jsx', '.json', '.tsx', '.ts', '.native.js'],
      },
    ],
    'react-native-reanimated/plugin',
  ],
}

What I mean by 'buggy' eslint/ts server:

Normal behavior:

image

Behavior after visiting file with reanimated import

image

After closing the file with reanimated import and restarting eslint server it's all good again :)

Also my pre-commit hook always fails with the same exact error as in the screenshot above.

Steps to reproduce

  1. Setup project with above dependencies and eslint config
  2. Create component using reanimated
  3. Close all files
  4. Go to app.tsx
  5. Create unsued var -> expect eslint error image
  6. Open component with reanimated use image
  7. Go back to app.tsx image
  8. Remove unused var and created another unused var -> expect no intellisense error image

Snack or a link to a repository

Private repo, snack makes no sense as it's local setup

Reanimated version

3.0.1 (same on 3.0.2, I dwongraded it for test)

React Native version

0.71.4

Platforms

Android, iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Paper (Old Architecture)

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

github-actions[bot] commented 1 year ago

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

Latropos commented 1 year ago

Something must be wrong with your eslint config, maybe its because of 'import/resolver'... Unfortunately it's not directly a problem with our library but with eslint so we have to close it.

pzatorski commented 8 months ago

The problem is with the import/resolver. Here is the workaround to make eslint happy: In your .eslintrc add react-native-reanimated to the import/ignore section.

settings: {
    react: {
      version: 'detect',
    },
    'import/resolver': {
      typescript: {},
    },
    'import/ignore': ['react-native', 'react-native-reanimated'],
  },