How to setup path aliases for development with Next.js & Jest

Blog post cover

I love Next.js and I wanted to share how you can setup path aliases for your imports. Sometimes you end up with various levels of file nesting and this can get messy fast.

Fortunately for us both Next.js and Jest support adding path aliases so we don't end up with something like this 👇

import Component from "../../../Component/Component";

For any medium to large react project you will have realized that due to the component nature of the library we end up doing a lot of importing. Let's find out how we can change the above into this 👇

import Component from "@/Component/Component";

for both development in Next.js and for our tests using the test Framework Jest.

Let's start with Next.js 😄

Next.js

Step 1 - Create a Next app

I'll start with a brand new project so you can see all the steps. For this I will create a new Next application using create-next-app so we can get up and running quickly. Start by running npx create-next-app. This is the basic file structure that comes with create-next-app 👇.

create-next-app starter file structure

Step 2 - Create some files to import

Next I'm going to create a src folder which is where I normally store the apps components, hooks etc. Let's add some files to our src folder to simulate how a real project might look 👇 .

our file structure after adding a src folder

Here I have created the following files

  • Header.js and Button.js components inside a components folder
  • __tests__ folder with our component test files
  • useStorage.js hook inside a hooks folder
  • config.js inside a lib folder

The contents of the files is not important. As long as you export something from your components which I will show you in a second.

Step 3 - Specify our path aliases

First we need to create a jsconfig.json file (or tsconfig.json if you're using TypeScript) and setup our path aliases. My setup looks like this 👇.

My jsconfig.json file with path alias setup

Here we can specify a base url that we start our import from. Commonly you will see the root . specified.

Next we can specify path aliases for our paths to the different folder locations. paths is an object where we start with our path alias and assign it an array of paths. A common syntax of alias is in the format "@/fileName/" but you can use anything you'd like.

Let's take our components alias as an example. We are saying we want to match the alias "@/components/" to the path src/components/ folder.

Step 4 - Checking that our aliases work

Now let's add some basic code to our components:

basic button component exporting a button

and the header is the same except it exports a <h2 /> tag 🙂. We can import them into other pages/components using the path aliases like this 👇.

importing our components using our path aliases

And to show you everything is working as expected in the browser 👇.

Our button and header components in the browser

Beautiful am I right 😉.

If we had code in our other files that we created inside our hooks and lib files we could import them like this 👇

importing something from our hooks and lib folders using path aliases

Of course we don't have anything in there but I wanted to show this is how you would import from those places 👏.

Jest

Step 1 - Install and configure the necessary files

I wanted to add this extra step for two reasons

  1. You should be testing your apps
  2. It's good to keep your imports consistent across development code and tests

First let's download the packages we need to work with Jest. I will install the following packages:

  • jest
  • babel-jest

jest if the primary package we need to install in order to use the Jest testing framework. While babel-jestwill help transform our code so we can include things like ES modules import syntax in our test files.

We also have to configure a .babelrc file with the following setup 👇

configure file for babel to work with next.js

What we are doing here is telling babel to use the custom preset for Next.js.

Next I'll add a test script to the package.json file so we can run our test suites like this 👇

Our test script for jest in the package.json file

Step 2 - Add our jest.config.js

Finally we can now get on to our aliases in Jest 👏. We first need to create a jest.config.js file. There are a couple of options we will pass in here and it looks something like this 👇.

Our jest.config file with path aliases setup along with ignore files and babel-jest transform

The first thing we do is use the testPathIgonrePattern which is defined as an array of strings that specify which paths we would like to skip when testing. Here we include the node_modules directory and the .next directory which contains our build files.

We don't want Jest looking in these directories for tests and we specify these paths starting at the root <rootDir>.

Next comes our path aliases. We need to use the moduleNameMapper property to map our aliases. It is a map of regular expressions and in this case we setup our three current aliases of @/components @/hooks and @/lib.

You can do this for any path you are likely to be importing regularly. If you wanted to move on to integration tests and import you pages into tests you could do the same for example @/page.

The order in which you setup these aliases could matter however. These patterns are checked by Jest from top to bottom therefore you have more specific rules you should include them first.

For more information check out the Jest - Configuring Jest.

Now if we add an empty test block to one of our files and attempt the import with the alias we won't receive any errors after running out test script. Our imports are now working as expected in Jest ✔.

Using our path alias successfully in Jest

Now you can actually start doing some work 😄.

Conclusion

I hope this quick setup was able to help. I think we can all agree that adding path aliases leads to nicer imports and cleaner code!

If you have any questions or comments let me know @Kieran6dev or in the comments below. I love hearing from you all!

if you feel like you need to support my content other than just reading or talking with me you can do so though Buy me a coffee below.

See you soon 👋