DEV Community

Erik Guzman
Erik Guzman

Posted on • Updated on

Mini-Tut: Create Alias for Rails Webpacker and VS Code Compatability

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 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

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

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.

    // 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.

    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

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.

    // 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

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

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.

    yarn add -D eslint-import-resolver-webpack

Now in your eslintrc file, you need to add the following:

    "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

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.

    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

Discussion (0)