DEV Community

Cover image for How To Create Absolute Imports In Vite React App: A step-by-step Guide

How To Create Absolute Imports In Vite React App: A step-by-step Guide

Andrew Ezeani on February 24, 2023

Table of Contents Introduction The Problem Prerequisite Setting up the Vite React project for absolute imports Creating a Vite React...
Collapse
 
irina_kats profile image
Irina Kats

Thanks for the article. I used it but it took me a while to figure out why TypeScript would not recognize Vite aliases. That is, Vite would compile but TypeScript would give an error, or the other way around: TypeScript gives no error but Vite will not compile. Eventually I found out that in addition to "baseUrl": "./src", in tsconfig I also had to give paths for my aliases.

That is, here is the combination that worked for me:
tsconfig.json:

    "baseUrl": "./src",
    "paths": {
      "@/*": ["*"],
      "@components/*": ["components/*"]
Enter fullscreen mode Exit fullscreen mode

vite.config.ts:

 resolve: {
    alias: {
      '@': '/src',
      '@components': '/src/components',
    },
  },
Enter fullscreen mode Exit fullscreen mode

import path:

import Text from '@components/text/text';

Without "paths" in the options above the import had not worked.

Collapse
 
andrewezeani profile image
Andrew Ezeani

I'm glad you found it helpful. It's nice you were able to fix the typescript aliases recognition issue you encountered. Do you mind if I reference your comment in the original article so it's easy to find for others with a similar problem?

Collapse
 
irina_kats profile image
Irina Kats

Thanks, Andrew, great that you're maintaining the article, go ahead and use my comment. Perhaps there might be other ways to fix this problem; if so I am interested to find out.

Collapse
 
khan94 profile image
Khan Julmagambetov

Hey, thanks for the article, I just wanted to ask, is there a way to convert src alias into empty string, so instead of src/components/Button we would import components/Button? thnx

Collapse
 
andrewezeani profile image
Andrew Ezeani • Edited

If you want to import directly from the components folder, all you need to do is add a new property named components to the alias object. Take a look at the example code provided below:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      src: "/src",
      components: "/src/components"
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can opt for a different approach by creating an array that contains all your file names as shown below.

const fileNames = ['src', 'components'];
Enter fullscreen mode Exit fullscreen mode

Using the array reduce method, you can conveniently generate an object with the respective file paths, as demonstrated below:

const filePaths = fileNames.reduce((acc, cur) => ({
  ...acc, [cur]: `/${cur === "src" ? cur : "src/" + cur}`
}), "");
Enter fullscreen mode Exit fullscreen mode

Once you have the filePaths object, you can easily include it using the JavaScript spread operator within the alias argument. Here is a code snippet:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      ...filePaths
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

You can use this technique to effortlessly create a new absolute import path by simply adding the desired file name to the fileNames array.

Collapse
 
gregfenton profile image
gregfenton • Edited

I believe that the above code in the .reduce() should have cur and not curr, and it should pass an empty string as the initial value for the reduce:

const filePaths = fileNames.reduce(
    (acc, cur) => ({
      ...acc,
      [cur]: `/${cur === 'src' ? cur : 'src/' + cur}`
    }),
    ''
  );
Enter fullscreen mode Exit fullscreen mode

also, you can programmatically get the list of fileNames with:

import fs from 'fs';


const folders = fs.readdirSync('./src', { withFileTypes: true });
const fileNames = folders.filter((dirent) => dirent.isDirectory())
                         .map((dirent) => dirent.name);

console.log(`filePaths: ${JSON.stringify(filePaths, null, 2)}`);
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
andrewezeani profile image
Andrew Ezeani

Thanks for the correction and feedback. I learnt something new!

Thread Thread
 
andrewezeani profile image
Andrew Ezeani

@gregfenton I just added a new section to the article where I aim to spotlight useful comments. Do you mind if I add your comment to it?

Thread Thread
 
gregfenton profile image
gregfenton

You are free to use what I provided however you would care to. Thanks for asking.

Collapse
 
heyprotagonist profile image
Anguram Shanmugam

Awesome Tip Mate 🍻

Collapse
 
andrewezeani profile image
Andrew Ezeani

Thank you. I’m glad you found it helpful

Collapse
 
moamal2000 profile image
Moamal Alaa

Good job, That was helpful.

Collapse
 
scrodrig profile image
scrodrig

It worked like a charm. The only thing that did not work for me was VSCode IntelliSence suggesting the absolute routes :(

Collapse
 
houria47 profile image
Houria F. Yaseen

Consider adding this line in settings.json

"javascript.preferences.importModuleSpecifier": "non-relative"
Enter fullscreen mode Exit fullscreen mode

It worked for me after hours of searching. Source: stackoverflow, question - 47330773

Collapse
 
dvgy profile image
GAURAV YADAV

How did you configure eslint for this?

Collapse
 
kunaljain0212 profile image
Kunal Jain

Is there a way to convert all existing relative imports in a huge codebase to the format you've shared in the blog? Maybe through a script or something similar?