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.