DEV Community

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

Posted on • Updated on

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

Table of Contents

Introduction

Relative imports are the default way to reference source files in JavaScript projects. However, as the codebase becomes more extensive and complex, it can become difficult to locate the correct source file when you need to make changes or during debugging. Absolute imports provide a clear and consistent way to locate and reference source files, making organising and maintaining your project easier.

In this guide, I will teach you how to create absolute imports in a Vite-powered React app, step by step. I will also teach you how to set up your project, configure the Vite.config.js file to resolve absolute imports in your app, how to import components using absolute paths, and how to configure vscode Intellisense to recognize absolute imports. By the end of this guide, you'll have learnt how to configure and use absolute imports in your Vite React app.

The problem

When building applications in React, depending on the level of complexity and file structure, an import statement could end up looking like this import Button from "../../../components/Button"; when importing components:

If during reorganization, the Button component is moved to a new folder, the app breaks down because the app can no longer locate the Button component in the current import path. Therefore, the import path needs to be updated to reflect the change. 

To fix it, an extra ../ is added to enable the app locate the Button component. This means that, whenever there is a change in the codebase all the import statements relating to the changed file will have to be updated. This could lead to longer time spent trying to locate a component when debugging the app.

Absolute imports on the other hand, reference source files using a fixed file path, regardless of the location of the file making the import. Absolute imports make it easier to locate the source file you're looking for, especially in larger codebases. In a Vite-powered React app, you can create absolute imports by configuring the Vite.config.js file to to resolve absolute imports in your app. For example the same Button component can be imported using the the absolute path syntax below:

import Button from "src/components/Button;

Prerequisite

  • The reader should have both Nodejs and Vite installed

  • The reader should be familiar with the es6 import and export syntax.

  • The reader should also know the basics of react

Setting up the Vite React project for absolute imports

To set up a Vite React project for absolute imports, you'll need to first create a React app using Vite. I will quickly walk you through the process below:

Creating a Vite React app

To create a Vite React app, simply run the below command in the command line:

npm create vite@latest – –template react demo-app

The command will create a boilerplate code for our react app. I named mine demo-app. You can name yours any name you want. Next, we move into our project directory by running the below code in the command line:

cd demo-app

Once you're in the project directory, run the below command to install all the necessary dependencies needed for the app to work

npm install

After the dependencies have been installed, simply run the command below to start up the development server

npm run dev

If you followed the instructions correctly, you should be seeing the below image in your browser

Starting page of a Vite-powered React app

Let's make some changes to the project. Create two new folders named components and pages respectively in the src directory. In the components directory create a new folder named Button. In this new folder, create a new file named Button.jsx, copy and paste the below code in it and save the file.



function Button() {
  return (
    <button>Random Button</button>
  )
}

export default Button


Enter fullscreen mode Exit fullscreen mode

Also create a new folder in the pages folder named Home. In this new folder, create a new file named Home.jsx, copy and paste the below code in it, then save the file.



function Home() {
  return (
    <>
      <h1>This is The HomePage</h1>
    </>
  );
}
export default Home;


Enter fullscreen mode Exit fullscreen mode

The next step, is to replace the boilerplate code present in the App.jsx file with the code below:



import "./App.css";
import Home from "./pages/Home";

function App() {
  return (
    <div className="App">
      <Home />
    </div>
  );
}

export default App;


Enter fullscreen mode Exit fullscreen mode

With this changes saved, this is what you should now see in your browser.

Updated web view after changes

Configuring the project to use absolute imports

To configure your app to use absolute import, you need to make some changes to the vite.config.js file, which is found at the root of your project directory.

Add the code below to the vite.config.js file



resolve: {
    alias: {
      src: "/src",
    },
  },


Enter fullscreen mode Exit fullscreen mode

Your vite.config.js should now look like this:



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

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      src: "/src",
    },
  },
});


Enter fullscreen mode Exit fullscreen mode

The development server will restart once you save the file. Now that absolute import has been configured for the project, any file can be imported using the alias created in the vite.config.js file.

Here's an example of how the Button component in our app can be imported:



import Button from "src/components/Button/Button"


Enter fullscreen mode Exit fullscreen mode

Now, whenever vite sees src at the beginning of our import path during the development or build process, it is resolved to ./src because of the configurations in the vite.config.file. This makes it easier to locate the component, even as your codebase grows.

Configuring VS Code IntelliSense

Currently, when you try to import the Button component, VS Code intelliSense still suggest file paths using relative path.

For example if you try importing the Button component in our Home page in the pages folder. VsCode still uses the relative import syntax to suggest the location of the component.

A gif showing VsCode relative path intelliSense suggestions

This is because we have not yet configured VsCode intelliSense to recognize absolute import paths. To configure VS Code intelliSense, you simply need to create a new file named jsconfig.json in the root directory of your project and add the following code to the file:



{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "src/*": ["./src/*"],
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

The intellisense configurations for your Vscode will automatically be updated once the file is saved. Now, when the Button component is being imported again, the file path suggestion provided by VsCode intelliSense is the absolute import path.

A gif showing VsCode intelliSense using absolute path for suggestions

Practical Tips from Readers

This section was added to spotlight helpful tips provided by readers that might otherwise get lost in the comment section.

  • This tip by @divensky, is a good solution for fixing issues with Typescript not recognizing path aliases

Conclusion

By following the steps outlined in this guide, you have learnt how to set up a vite React app, how to configure the vite.config.js file to resolve absolute paths in your app, how to import components using absolute imports and how to configure VsCode intellisense to recognize absolute import path in your app.

Top comments (17)

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
 
ajith_pious_0c0f9e171c64f profile image
ajith pious • Edited

installing the plugin vite-tsconfig-paths and adding the below in tsconfig.json

"compilerOptions": {
    // ...other options
    "paths": {
      "*": ["./src/*"]
    }
  }
Enter fullscreen mode Exit fullscreen mode

and vite.config.js with

import tsconfigPaths from 'vite-tsconfig-paths';
export default {
  plugins: [tsconfigPaths(), react(),],
};
Enter fullscreen mode Exit fullscreen mode
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?