DEV Community

Cover image for Cleaner imports with aliases in react and typescript ✨✨
Emmanouil Liakos
Emmanouil Liakos

Posted on

Cleaner imports with aliases in react and typescript ✨✨

The problem with relative imports

As a project's been growing, you might've found yourself making imports like this:

import { someUtil } from '../../../../src/utils';
import defaultExport, { SomeModule } from '../../../src/modules/dummy-module';
Enter fullscreen mode Exit fullscreen mode

This can quickly get out of hand, resulting in many chaotic imports from some deeply nested folders. This would get a lot cleaner, if we could do something like this:

import { someUtil } from '@/utils';
import defaultExport, { SomeModule } from '@dummy-module';
Enter fullscreen mode Exit fullscreen mode

We essentially mapped @ to src folder and @dummy-module to src/modules/dummy-module folder which allowed us to reference them directly using their alias.

Configuring aliased imports

TypeScript configuration

In order for TypeScript to become aware of our alias paths, we must define them inside our tsconfig.json file, under compilerOptions:

// tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    ...,
    "paths": {
      "@/*": ["src/*"], // 👈 This line allows us to import from folders inside "src" folder using "@"
      "@dummy-module": ["src/modules/dummy-module"], // 👈 This line allows us to import from the "dummy-module" folder itself using "@dummy-module"
      "@dummy-module/*": ["src/modules/dummy-module/*"] // 👈 This line allows us to import from folders inside "src/modules/dummy-module" folder using "@dummy-module"
    }
  },
    ...
}
Enter fullscreen mode Exit fullscreen mode

We are now able to import using the above aliases. In case TypeScript still complains about your imports, then create a separate tsconfig.paths.json file next to tsconfig.json (inside root directory), to extend your base config from:

// tsconfig.paths.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"], // 👈 This line allows us to import from folders inside "src" folder using "@"
      "@dummy-module": ["src/modules/dummy-module"], // 👈 This line allows us to import from the "dummy-module" folder itself using "@dummy-module"
      "@dummy-module/*": ["src/modules/dummy-module/*"] // 👈 This line allows us to import from folders inside "src/modules/dummy-module" folder using "@dummy-module"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

and modify tsconfig.json like this:

// tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    ... 👈 Remove "paths" option
  },

  "extends": "./tsconfig.paths.json" // 👈 Add this line
}
Enter fullscreen mode Exit fullscreen mode

Webpack configuration

In a react app, you've most likely used create-react-app as a scaffold. So you need to override its internal webpack configuration, in order to let the bundler know how to resolve your aliases during build time. To do that without ejecting, you can use craco:

npm i @craco/craco
Enter fullscreen mode Exit fullscreen mode

or

yarn add @craco/craco
Enter fullscreen mode Exit fullscreen mode

Next, create a craco.config.js file at your project’s root and paste this code:

const path = require('path');

module.exports = {
  webpack: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@dummy-module': path.resolve(__dirname, 'src/modules/dummy-module'),

    },
  },
};
Enter fullscreen mode Exit fullscreen mode

Finally, replace react-scripts with craco inside package.json file:

"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
 }
Enter fullscreen mode Exit fullscreen mode

and restart your app:

yarn start
Enter fullscreen mode Exit fullscreen mode

And that's all folks 🥳

Discussion (1)

Collapse
miketalbot profile image
Mike Talbot

Create React App since v5 does not need Craco to handle tsconfig.json without the need for Webpack aliases.