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.
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.
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 \
.
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!
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.
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!
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
Top comments (0)