React native Typescript path alias unable to resolve module

Viewed 5483

so basically, I created my React Native with Typescript using the commandline in RN homepage: npx react-native init MyApp --template react-native-template-typescript

After that, I ran the project and it was built successfully. However, when I added the path alias to import my file, it threw an error: Unable to resolve module #folder/file from ... could not be found within the project or in these directories: node_modules

I've already followed some tutorials and bug resolves on Google but I've met no luck.

Here is my .babelrc file (I tried to change the file from babel.config.js to .babelrc as some resolver said but it still didn't work)

{
  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    [
      "module-resolver",
      {
        "root": ["./src"],
        "extensions": [
          ".js",
          ".jsx",
          ".ts",
          ".tsx",
          ".android.js",
          ".android.tsx",
          ".ios.js",
          ".ios.tsx"
        ],
        "alias": {
          "#src/*": [
            "./src/*"
          ],
          "#configs/*": [
            "./src/config/*"
          ],
          "#actions/*": [
            "./src/redux/actions/*"
          ],
          "#reducers/*": [
            "./src/redux/reducers/*"
          ],
          "#store/*": [
            "./src/redux/store/*"
          ]
        }
      }
    ]
  ]
}

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "esnext", 
    "module": "commonjs",
    "lib": [
      "ES2017",
      "DOM",
      "ES2015",
      "ES2015.Promise"
    ], 
    "allowJs": true, 
    "jsx": "react-native",
    "noEmit": true, 
    "incremental": true,
    "importHelpers": true,
    "isolatedModules": true,
    "strict": true,
    "moduleResolution": "node",
    "baseUrl": ".", 
    "paths": {
      "#src/*": [
        "src/*"
      ],
      "#configs/*": [
        "src/config/*"
      ],
      "#actions/*": [
        "src/redux/actions/*"
      ],
      "#reducers/*": [
        "src/redux/reducers/*"
      ],
      "#store/*": [
        "src/redux/store/*"
      ]
    }, 
    "types": ["jest"],
    "allowSyntheticDefaultImports": true, 
    "esModuleInterop": true, 
    "skipLibCheck": false, 
    "resolveJsonModule": true 
  },
  "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
  ]
}

My folders and files structure

├───assets
├───components
├───config
│       constants.ts
│
└───redux
    ├───actions
    │       index.ts
    │       stateActions.ts
    │
    ├───reducers
    │       index.ts
    │       stateReducer.ts
    │
    └───store
            index.ts

Really looking forward to receive you guys answers. Thank you so much

P/s: if you dont mind, please take a look at my repository: https://github.com/NotJackieTruong/rn_test_typescript

3 Answers

To make this work just need add package.json file to each directory you want to access with one property name in it. For example:

├───assets
└───components
    └───package.json

package.json content:

{
  "name": "components"
}

And then you can import like this:

import SomeComponent from 'components/SomeComponent';

There is also a good article describing how this works.

tsconfig.json

 "baseUrl": ".", 
 "paths": {
      
      // this is for src directory
      "@*": ["src/*"],
      "@configs/*": ["src/config/*"
      ],

babel.config.js

module.exports = function (api) {
    api.cache(true);
    return {
        presets: ["babel-preset-expo"],
        plugins: [
            [
                "module-resolver",
                {
                    alias: {
                        "@config": "./src/config",
                         ....
                        
                    }
                }
            ]
        ]
    };
};


        }

add this to your tsconfig.json

"include": ["./src/**/*"]

then restart your TypeScript Server

Cmd+Shift P then choose TypeScript: Restart TS server

Edit: this is the tsconfig.json I'm using if that helps

{
  "compilerOptions": {
    "noImplicitAny": true,
    "noEmit": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "jsx": "react-native",
    "lib": ["es6", "dom", "esnext"],
    "moduleResolution": "node",
    "baseUrl": ".",
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "paths": {
      "@app/*": ["./src/*"]
    }
  },
  "include": ["src/**/*", "./App.tsx"],
  "extends": "expo/tsconfig.base"
}

Related