Mini-Tut: Create Alias for Rails Webpacker and VS Code Compatability
Tags: rails, webpack, javascript, tutorial
Published: 2019-12-13 17:42:02

Using relative path are great when including files that are right next to your current file but can get really out of hand when dealing with more complex folder structures or when you start looking to refactor and shuffle around files. 

I recently did this for my [Stream Closed Captioner Twitch extension](https://stream-cc.gooseman.codes/) Ruby On Rails project and thought I would share my experience doing it. Even though these steps are for Ruby on Rails Webpacker these steps should still work for any project using Webpack with some adjustments.

# Diving In

Right now this is the import path for `obs-websocket` and I really wasn't digging the complexity that will come about when starting to move around files and folder structure starts to get deeper.

![https://imgur.com/1WG4C3O.png](https://imgur.com/1WG4C3O.png)

Below is where I want to be. Regardless where I move this `OBSConnector` class I know exactly where `obs-websocket` is, much mo' betta I think.

![https://imgur.com/WXsEUA8.png](https://imgur.com/WXsEUA8.png)

To achieve this well be making an alias in our Webpack configuration and some configuration files for your Visual Studio Code and ESLint to understand what the alias means.

# Creating an Alias for Webpacker

In your Rails project, you will create a new configuration file dedicated to your new alias configuration. Create `config/webpack/alias.js`. 
```javascript
    // config/webpack/alias.js
    const path = require('path');
    
    module.exports = {
      resolve: {
        alias: {
          '@': path.resolve(__dirname, '../../app/javascript/src/'),
        },
      },
    }
```

In this `alias.js` you will create your alias, in my case `@` is mine for the root directory for all my front end source files. If your using the default webpacker configurations the file path to your JavaScript files should be the same... roughly.

Next, you will need to update your environment file so you merge your new webpack settings with our existing ones. Open up `config/webpack/environment.js` and add the lines I indicated with my comments.

```javascript
    const { environment } = require('@rails/webpacker')
    // OVER HERE 🙌 ----- Require the new alias file
    const customConfig = require('./alias')
    
    const nodeModulesLoader = environment.loaders.get('nodeModules')
    if (!Array.isArray(nodeModulesLoader.exclude)) {
      nodeModulesLoader.exclude = (nodeModulesLoader.exclude == null)
        ? []
        : [nodeModulesLoader.exclude]
    }
    
    // DOWN HERE ALSO 🙌 ----- Merge new resolve alias to our existing configuration
    environment.config.merge(customConfig)
    
    module.exports = environment
```

Boom now you have an aliased file path for your imports. Now when you use `@` in your import path it will point to the root of your front end files. But you're not done yet, after a while you will notice your VS Code and ESLint will not know what the heck `@` is. You will see the dreaded jagged red lines of DOOM.

# Getting VS Code and ESLint to Play Nice

So after making your changes and trying to import using your fancy new alias, you will notice a problem. Where is the heckin intellisense auto-suggest path thingy? In the image below you will see it doesnt show the folders and files after doing the usual `\`.

![https://imgur.com/iPtCTv8.png](https://imgur.com/iPtCTv8.png)

So you get this to work you need to tell VS Code what `@` means and what file path it starts at. The `jsconfig.json` is the tool for this job. Create the `jsconfig.json` at the root of your project. 

```json
    // jsconfig.json
    {
      "compilerOptions": {
        "baseUrl": "./app/javascript/src",
        "paths": {
          "@/*": ["./*"]
        }
      }
    }
```

I hope this reads pretty straight forward. It just sets the base URL where our front end files are and what `@` points to in the path.

Yay now the path intellisense thing is working!

![https://imgur.com/utK2bY0.png](https://imgur.com/utK2bY0.png)

But dang it! Now ESLint in complaining that it doesnt think installed this module even though this is just an alias. You might see something like in the image below.

![https://imgur.com/3T7OAK6.png](https://imgur.com/3T7OAK6.png)

But everything is all good we just need to also tell ESLint about our alias. To help ESLint out with being able to resolve alias path import we need the ` eslint-import-resolver-webpack` plugin. Let's install it.
```bash
    yarn add -D eslint-import-resolver-webpack
```

Now in your `eslintrc` file, you need to add the following:
```javascript
    "settings": {
        "import/resolver": {
          alias: {
            map: [
              ['@', './app/javascript/src']
            ]
          }
        },
      }
```

Just like with the `jsconfig.json` file for telling VS Code about the `@` alias, this file tells ESLint about the `@` also.

Yay now everything is working like it should and now angry red lines!

![https://imgur.com/WXsEUA8.png](https://imgur.com/WXsEUA8.png)

# Wrapping It UP

Now instead of doing a relative file path, we can now use absolute paths. I think this feels a lot cleaner then dots galore.
```javascript
    import { Controller } from 'stimulus'
    import { formatDistanceStrict } from 'date-fns'
    import { createSpeechChannel } from '@/channels/speech-channel'
    import { createTranslationChannel } from '@/channels/translation-channel'
    import { initOBSToggleListener } from '@/obs-websocket-ui'
    import SpeechRecognitionHandler from '@/SpeechRecognitionHandler'
    import { notChromeWarning } from '@/ui/modals/chrome-warning'
    import { displaySnackbar } from '@/ui/mdc-snackbar'
    
    // ...
```

Hopefully, this ends up being useful and cheers.

---
Want to hang out while I work on this project and other things? You can catch me streaming on Twitch @ https://twitch.tv/talk2megooseman