In order to avoid '../../../../' style relative imports in a TypeScript based React Native app, I would like to configure the app so that I can use absolute imports instead.
It is important that the configuration also supports Jest unit tests.
I created the app using npx react-native init MyTestApp --template typescript
React Native version: 0.60.5
What is the exact configuration I would need to achieve this?
To be able to use absolute paths in TypeScript we can set the baseUrl property in the tsconfig. json file. With this, we define src as our root directory (for module resolution).
According to create-react-app Docs, We can use absolute imports in our react project by configuring a jsconfig. json / tsconfig. json (for typescript projects) file in the root of our project. If you're using TypeScript in your project, you will already have a tsconfig.
// Meh import config from '../../../../../../../config'; // Awesome! import config from '@cuteapp/config';
yarn add --dev babel-plugin-module-resolver
babel.config.js
module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ [ require.resolve('babel-plugin-module-resolver'), { cwd: 'babelrc', extensions: ['.ts', '.tsx', '.js', '.ios.js', '.android.js'], alias: { '@cuteapp': './app' } } ], 'jest-hoist' ] };
tsconfig.json
{ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "isolatedModules": true, "jsx": "react", "lib": ["es2015", "es2015.promise", "es2016.array.include", "dom"], "strict": true, "moduleResolution": "node", "baseUrl": "./", "paths": { "@cuteapp/*": ["app/*/index", "app/*"] }, "noEmit": true, "resolveJsonModule": true, "target": "esnext", "types": ["jest"] }, "exclude": ["node_modules", "babel.config.js", "metro.config.js"] }
Summary:
The npm package babel-plugin-module-resolver
is needed, as well as some configuration in tsconfig.json
and babel.config.js
Step by step:
Install babel-plugin-module-resolver
using npm or yarn.
npm i babel-plugin-module-resolver --save-dev # Or (If you're using yarn): yarn add --dev babel-plugin-module-resolver
tsconfig.json
: Add "baseUrl": "."
to compilerOptions
babel.config.js
: Add a key named plugins
with the following value:
[ [ 'module-resolver', { extensions: [ '.js', '.jsx', '.ts', '.tsx', '.android.js', '.android.tsx', '.ios.js', '.ios.tsx' ], root: ['.'] } ] ]
Complete configuration:
tsconfig.json
:
{ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "isolatedModules": true, "jsx": "react", "lib": ["es6"], "moduleResolution": "node", "noEmit": true, "strict": true, "target": "esnext", "baseUrl": "." }, "exclude": ["node_modules", "babel.config.js", "metro.config.js", "jest.config.js"] }
babel.config.js
:
module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ [ 'module-resolver', { extensions: [ '.js', '.jsx', '.ts', '.tsx', '.android.js', '.android.tsx', '.ios.js', '.ios.tsx' ], root: ['.'] } ] ] };
This is for a clean new project created using npx react-native init MyTestApp --template typescript
on React Native version 0.60.5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With