Solve Module Import Aliasing for Webpack, Jest, and VSCode

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

Justin Tulk
Oct 30, 2017 · 2 min read

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.

Justin Tulk

Written by

Senior Software Engineer. Making computers do stuff since 2011.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade