Search code examples
typescriptreact-nativeimporttsconfignative-base

Problem with import component in react-native - typeScript


I have a problem with import my component when it's in ./src/components/CustomButton/index.tsx and when im using defined paths in tsconfig. Then my import looks like import CustomButton from '@components/CustomButton'

But when i save it not in index.tsx and without using directory but just in /components/CustomButton.tsx and then import CutomButton from '../components/CustomButton.tsx' everything works fine.

How to make first version work properly?

Import error: enter image description here

CustomButton index.tsx

import {Button} from 'native-base';


const CustomButton = ({
  children,
  dark,
  onPress,
  isDisabled,
  bold,
  isLoading,
  mt,
}: any) => (
  <Button
    _text={{
      color: `${dark ? 'white' : 'black'}`,
      fontWeight: `${bold ? 'bold' : 'normal'}`,
      fontSize: 16,
    }}
    bg={dark ? 'muted.20' : 'muted.10'}
    colorScheme="muted"
    onPress={onPress}
    isDisabled={isDisabled}
    isLoading={isLoading}
    style={{borderRadius: 10}}
    p="4"
    mt={mt}>
    {children}
  </Button>
);

export default CustomButton;

tsconfig

{
  "extends": "@tsconfig/react-native/tsconfig.json",
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "sourceMap": false,
    "jsx": "react-native",
    "allowJs": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "declaration": true,
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "baseUrl": "./src",
    "paths": {
      "@*": ["/*"],
      "@api/*": ["/apiActions/*"],
      "@components/*": [
        "/components/*"
      ],
      "@context/*": [
        "/Context/*"
      ],
      "@interfaces/*": [
        "/Interfaces/*"
      ],
      "@utils/*": [
        "/utils/*"
      ]
    }
  },
  "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
  ]
}

How to make first version work properly? I've search a lot here and in other pages but i didn't find the answer


Solution

  • it has been a while since I set up my react-native project.

    I can't remember for sure, but I believe this was my solution:

    1. add babel-plugin-root-import to devDependencies

      yarn add -D babel-plugin-root-import

    2. open babel.config.js and add babel-plugin-root-import in plugins

    module.exports = function (api) {
       return {
          ...
          plugins: [
            // Add this line
             [
             'babel-plugin-root-import',
                 {
                    root: __dirname,
                    rootPathPrefix: '@',
                    rootPathSuffix: 'src',
                 },
          ]
          ]
       }
    }
    

    If it doesn't work, please let me know and I'll try to remember it again.

    Another solution is to add package.json in your folder. For example on components folder add package.json and write this:

    {
       "name": "@components"
    }
    

    Additionally, I believe you can write your tsconfig.json file more succinctly by removing

          "@api/*": ["/apiActions/*"],
          "@components/*": [
            "/components/*"
          ],
          "@context/*": [
            "/Context/*"
          ],
          "@interfaces/*": [
            "/Interfaces/*"
          ],
          "@utils/*": [
            "/utils/*"
          ]
        }
    

    in your paths and change to this

    "paths": {
       "@*": ["src/*"]
    },