Solve Module Import Aliasing for Webpack, Jest, and VSCode

Never dig out with `./../../../..` again!

Scale any project past a certain point of complexity, and you’ll find yourself traversing up and down your file system in your components trying to resolve your imports. Here’s how to configure aliasing to make things easier.

If you’re not familiar with the concept of aliasing, it turns a file like this:

import React from 'react'
import { connect } from 'react-redux'
import { someConstant } from './../../config/constants'
import MyComponent from './../../../components/MyComponent'
import { myActionCreator } from './../../../ducks/someReducer'

into this:

import React from 'react'
import { connect } from 'react-redux'
import { someConstant } from 'Config/constants'
import MyComponent from 'Components/MyComponent'
import { myActionCreator } from 'Ducks/someReducer'

For this post, assume an app structure as follows:

MyApp/
dist/
src/
config/
components/
ducks/
shared/
jsconfig.json
package.json
webpack.config.js

Webpack

Without any additional plugins, Webpack allows aliasing module imports through the resolve.alias property in your config.

module.resolve = {
alias: {
Config: path.resolve(__dirname, "..", "src", "config"),
Components: path.resolve(__dirname, "..", "src", "components"),
Ducks: path.resolve(__dirname, "..", "src", "ducks"),
Shared: path.resolve(__dirname, "..", "src", "shared"),
App: path.join(__dirname, "..", "src")
}
}

Complication 1: While Webpack knows how to resolve these aliases now, VS Code doesn’t, so tools like Intellisense won’t work.


VS Code

Making VS Code ‘smarter’ by telling it how to resolve these aliases is as easy as adding a jsconfig.json file to your project at the root. Use the exclude property to keep VS Code from slowing down by searching node_modules or compiled folders (like dist).

{
"compilerOptions": {
"target": "es2017",
"allowSyntheticDefaultImports": false,
"baseUrl": "./",
"paths": {
"Config/*": ["src/config/*"],
"Components/*": ["src/components/*"],
"Ducks/*": ["src/ducks/*"],
"Shared/*": ["src/shared/*"],
"App/*": ["src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

Complication 2: While it’s great that VS Code can resolve these routes now, neither the webpack config or the jsconfig.json file is used by Jest, so tests will crash for these components.


Jest

Configure Jest in your package.json file using the moduleNameMapper property.

"jest": {
"moduleNameMapper": {
"^Config(.*)$": "<rootDir>/src/config$1",
"^Components(.*)$": "<rootDir>/src/components$1",
"^Ducks(.*)$": "<rootDir>/src/ducks$1",
"^Shared(.*)$": "<rootDir>/src/shared$1",
"^App(.*)$": "<rootDir>/src$1"
}

Complication 3: Make sure to place parent routes (such as <rootDir>/src) after child routes (<rootDir>/src/components) or you might get resolution errors. This goes for all three config files. I don’t know the deep rules for how resolution is achieved in each of these, but I had issues with having App defined first in these configs.

Like what you read? Give Justin Tulk a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.