Reputation: 311
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
Upvotes: 19
Views: 23486
Reputation: 9699
For expo v49+:
module-resolver is not required, you can remove it from babel-config
Add to app.json:
{
"expo": {
"experiments": {
"tsconfigPaths": true
}
}
}
paths
as usual in tsconfig.json
:{
"compilerOptions": {
"paths": {
"@/*": [
"src/*"
]
}
},
"extends": "expo/tsconfig.base"
}
Upvotes: 21
Reputation: 141
In my case I was not using expo
. I initiated my project using npx react-native init <App name>--template react-native-template-typescript
. I ran into issues once I added path aliases to my .babelrc
and tsconfig.js
. I tries several instructions but nothing worked. My successful attempt was.
node_modules
and yarn.lock
babel.config.js
into .babelrc
. (Cannot gaurantee if this had to do with the success).yarn
to install all the dependencies.yarn start --reset-cache
to install and run the app while removing the metro-cache.Upvotes: 2
Reputation: 1116
After long efforts and trials, I was able to make the path alias work with "@" as follows;
Note: My all codes in src directory.
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./src'],
alias: {
'@': './src'
}
}
]
]
};
tsconfig.json
{
"extends": "@tsconfig/react-native/tsconfig.json",
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@/*": ["*"]
}
},
"include": ["src"]
}
Upvotes: 0
Reputation: 1134
For those who still stuck with the issue with all solutions you have just make sure the following:-
npm install --save-dev babel-plugin-module-resolver
or
yarn add --dev babel-plugin-module-resolver
babel.config.js or .babelrc
make sure this is development not production in babel <<<<<<<<<<<<< VIP
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-reanimated/plugin'],
env: {
development: { // <<< make sure this is development not production
plugins: [
'react-native-paper/babel',
[
'module-resolver',
{
root: ['./src'],
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx',
'.android.js',
'.android.tsx',
'.ios.js',
'.ios.tsx',
],
alias: {
'@hooks': ['./src/hooks'],
'@familyway': ['./src'],
'@assets': ['./src/Assets'],
'@components': ['./src/Components'],
'@constants': ['./src/Constants'],
'@helpers': ['./src/helpers'],
'@onboarding': ['./src/onBoarding'],
'@redux': ['./src/redux'],
'@screens': ['./src/Screens'],
'@lib': ['./src/lib'],
'@containers': ['./src/containers'],
},
},
],
],
},
},
};
ok now with the tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"lib": [
"dom",
"dom.iterable",
"esnext",
"esnext.asynciterable",
"esnext.intl",
"esnext.symbol",
"esnext.array"
],
"allowSyntheticDefaultImports": true,
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"noImplicitAny": true,
// "noImplicitReturns": true,
// "noImplicitThis": true,
"esModuleInterop": true,
"alwaysStrict": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-native",
"incremental": true,
"noEmitOnError": true,
"baseUrl": "./src",
"paths": {
"@hooks/*": ["hooks/*"],
"@components/*": ["Components/*"],
"@assets/*": ["Assets/*"],
"@screens/*": ["Screens/*"],
"@constants/*": ["Constants/*"],
"@helpers/*": ["helpers/*"],
"@onboarding/*": ["OnBoarding/*"],
"@redux/*": ["redux/*"],
"@containers/*": ["containers/*"],
"@lib/*": ["lib/*"]
}
},
"include": [
"next-env.d.ts",
"additional.d.ts",
"src/**/*.ts",
"src/**/*.js",
"src/**/*.tsx",
"./App.tsx",
"./src/**/*",
"src/**/*",
"src/**/*.*"
],
"exclude": ["node_modules"]
}
Upvotes: 1
Reputation: 445
In tsconfig.json
{
...
"compilerOptions":{
...
"baseUrl":"."
"paths":{
"@folder": "src/folder" <--assuming app logic is in src/
}
}
}
In babel.config.js
module.exports = {
...
plugins: [
["module-resolver",{
"alias":{
"@folder": "./src/folder",
}
}]
],
};
Uninstall the app from emulator/device
Restart the metro server yarn start --reset-cache
Build the app yarn run android/ios
Upvotes: 4
Reputation: 49293
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",
....
}
}
]
]
};
};
}
Upvotes: 5
Reputation: 1144
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"
}
Upvotes: 3
Reputation: 672
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.
Upvotes: 4