Mastering Project Maintainability with Module Resolver
Tags: javascript, babel, typescript
Published: 2024-05-15 15:36:30

---
title: Mastering Project Maintainability with Module Resolver
published: true
description: Babel plugin to easy development in complex project setup
tags: javascript, babel, typescript
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-05-14 14:25 +0000
---

# Why you need Module Resolver?
Imagine working on a large-scale project containing numerous files such as components, screens, utils, etc.

Over time, the complexity of the project increases with multiple levels of imports. This eventually leads to a drop in developer productivity, making it difficult to onboard new developers. The impact is more pronounced on junior developers, who often get lost in the myriad of files.

![Snapshot of project folder structure containing multiple folders, inner folders and files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l31zy6xulvacjz0s1bbg.png)

With this project structure, importing components would look like this:

```js
import Button from "../../components";
import Delete from "../../actions";
import utils from "../../utils";
```

To tackle all of the above issues, we can use the Module Resolver Babel plugin. This plugin helps simplify and manage your import paths, making your project more organized and maintainable.

# What is Module Resolver? 
Module Resolver is tool or mechanisms to covert relative paths to aliases for your entire Javascript/Typescript project. 

## How to setup project to use Module Resolver?
If you are using JavaScript, then make the following changes in the jsconfig.json file or create a new jsconfig.json file. If you are using TypeScript, either modify the existing tsconfig.json file or create a new tsconfig.json file with the following code: 

```json
{
    "compilerOptions": {
      "jsx": "react",
      "baseUrl": "./",
      "paths": {
        "@myapp/components": ["./src/components"],
        "@myapp/actions": ["./src/actions"],
        "@myapp/screens": ["./src/screens"],
        "@constants": ["./src/constants"],
        "@utils": ["./src/utils"]
      }
    },
    "exclude": ["node_modules"]
} 
```

After making this change, restart your IDE for it to take effect. You can also replace @myapp with your project name to personalize your project setup.

Here’s how you can do it:
### *Metro Bundler (React/React Native)

If your project is using Metro Bundler, which is the default bundler for React and React Native setups, modify the metro.config.js file with the following code:

```js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

/**
 * Metro configuration
 * https://reactnative.dev/docs/metro
 *
 * @type {import('metro-config').MetroConfig}
 */

const config = {
    resolver: {
        extraNodeModules: {
            "@myapp/components": `${__dirname}/src/components`,
            "@myapp/actions": `${__dirname}/src/actions`,
            "@myapp/screens": `${__dirname}/src/screens`,
            "@constants": `${__dirname}/src/constants`,
            "@utils": `${__dirname}/src/utils`
        }
    }
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
```

### *Babel

If your project is using Babel, you can use the babel-plugin-module-resolver to manage your module paths. First, install the plugin:

```bash
npm install --save-dev babel-plugin-module-resolver
```
Then, update your babel.config.js file with the following code:

```js
module.exports = {
  plugins: [
    [
      "module-resolver",
      {
        "root": ["./src"],
        "alias": {
          "@myapp/components": "./components",
          "@myapp/actions": "./actions",
          "@myapp/screens": "./screens",
          "@constants": "./constants",
          "@utils": "./utils"
        },
        "extensions": [".js", ".ios.js", ".android.js", ".json"]
      }
    ]
  ]
};

```

### * Webpack

If your project is using Webpack, you can configure it to resolve custom module paths by modifying the webpack.config.js file as follows:

```js
module.exports = {
  resolve: {
    alias: {
      "@myapp/components": path.resolve(__dirname,"src/components"),
      "@myapp/actions": path.resolve(__dirname,"src/actions"),
      "@myapp/screens": path.resolve(__dirname,"src/screens"),
      "@constants": path.resolve(__dirname,"src/constants"),
      "@utils": path.resolve(__dirname,"src/utils")
    },
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  },
};
```

After module resolver changes, you can import like this: 
```js
import Button from "@myapp/components";
import Delete from "@myapp/actions";
import utils from "@constants";
```

Feel free to tweak it according to your personal style or any additional points you might want to add!

Happy Coding!
Feel free to reach out to me on linkedin - https://www.linkedin.com/in/rameshvishnoi/