Smelly Code

How to "require" with aliases πŸ”

May 08, 2021 βˆ™ πŸ‘¨πŸ»β€πŸ« 2 min

I recently worked on a NodeJs based command-line app. The app had significant depth in its directory structure. The depth in directory structure unintentionally added a wild amount of relativeness to require statements.

const { utils } = require('../../../../lib'); const commands = require('../../../commands');

When I encountered these statements, I realized the need of aliases. I search for nodejs require aliases and landed on the gist: Better local require() paths for Node.js. It recommended almost 8 different solutions. I found the alias approach more promising and convincing because of following reasons:

  • Clean cross platform solution.
  • Uses a well maintained popular npm package: module-alias.
  • Aliases can be prefixed with symbols(such as @) to tip off fellow developers.

The alias approach had a few downsides which could be resolved easily.

  • Littering package.json with aliases(can be avoided by manually adding aliases).
  • Requires additional steps for linter and editor.

After evaluating trade offs, I installed module-alias and added aliases in package.json.

{ "_moduleAliases": { "@lib": "lib", "@constants": "constants", "@commands": "commands" } }

I also replaced relative require statements with aliases and tested the change.

const { utils } = require('@lib'); const commands = require('@commands');

Things were working as expected. But gradually ESLint started screaming:

es lint import no resolve

It was expected because EsLint can not resolve the path aliases. I pacified ESLint using eslint-import-resolver-alias with below config:

{ "import/resolver": { "alias": [ ["@lib", "./lib"], ["@constants", "./constants"], ["@commands", "./commands"] ] } }

After a while, I found that features such as IntelliSense, quick navigation between modules, etc. stopped working for aliased paths. It’s because VS Code was not aware of the aliased path mappings. I added the aliased path mappings to compilerOptions of jsconfig.json for VS Code.

{ "compilerOptions": { "baseUrl": "./", "paths": { "@lib": ["./lib"], "@constants": ["./constants"], "@commands": ["./commands"] } } }

It started working as usual. Tada πŸŽ‰! I was happy. EsLint was happy. VS Code was happy. Everyone was happy.

Hi, I am Hitesh.