First and foremost, this is my first post to dev.to! I've never really blogged in the past, but if you'd like to check out my other (3) blog posts you can head on over to josefaidt.me/blog.
The tooling surrounding the JavaScript community is uncanny. There are so many useful tools out in the wild such as Webpack, Rollup, create-react-app, Gatsby, VSCode extensions, and let's not forget npm & Yarn! Despite this I feel we often overlook our most important tool, the command line.
Though daunting at first, the command line has proven its reliability and operability time after time with utilities like Homebrew and Git. Even the lower-level, out-of-the-box utilities like cat
and grep
are incredibly useful. If you're not the type of person that prefers point-and-click operations to do something as monotonous copying a file or peeking into a file's contents then you may already know the value bash/fish functions provide to drastically improve your existing workflow. But utilities don't have to be intense to be useful in the smallest regards.
Typing commands such as yarn workspace someWorkspace run someScript
can get tedious when you're in the middle of debugging an application. Or even specifying a configuration file in ESLint using eslint --config ~/.config/.eslintrc.js someDirectory
if you're using a global config file. Some commands or words can be easily fumbled when typing (e.g. "components" and "workspace"). This is where functions come in to play.
Fish Functions
Here we will be exploring functions in fish shell, specifically how we can use its functions to shorten our everyday commands such as the two noted above. The syntax is different compared to traditional bash aliases, but I hope to get you up and running in no time by guiding you through a few examples.
Let's start with yarn workspaces
by using an alias that is as fluid to type as it is short. Open your Fish configuration file via code ~/.config/fish/config.fish
and input the following:
function ywrs
command yarn workspaces $argv
end
That's it! You have just created your first function! Let's break this down:
-
function
: declaration keyword -
ywrs
: our alias, this is what we will be able to type in our terminal -
command yarn workspaces $argv
-
command
: keyword needed to tell the shell to "execute" the following command, just as how you would normally type into the terminal -
yarn workspaces
: the command we are wrapping -
$argv
: pass the remaining arguments to the defined command -
ywrs info
will thus executeyarn workspaces info
-
To test out your new function you will need to reload the fish configuration by reevaluating the config.fish
file (this is also done when a new shell session is created): source ~/.config/fish/config.fish
.
Now that you've got your feet wet, let's try a few more examples.
Yarn Workspace
function ywr
command yarn workspace $argv
end
Similar to the initial example, this will allow us to easily execute commands in a workspace via a keyword that is both short and easy to type.
ESLint
function eslint
command eslint --config ~/.eslintrc.js $argv
end
Here we are extending the existing, global eslint
command by specifying a configuration file that can now be used throughout your projects without setting up a project-level ESLint dotfile. For additional learning regarding global ESLint and VSCode, check out my other blog post.
An Intense Example
The ESLint example above allows you to use the eslint
command with a single configuration file, but what about automating the project-level install? Below we will discover how we can leverage functions, internal functions, and a bit of bash logic to install all of our ESLint dependencies and copy our global configuration file to the working directory.
function yawn
if test (count $argv) -lt 1; or test $argv[1] = "--help"
printf "Don't yawn too loud now, I need a package name"
else if test (count $argv) -eq 1
switch $argv[1]
case 'eslint'
_install_eslint
case '*'
echo "Doesn't look like I have that package, try again."
end
else
echo $argv
end
end
function _install_eslint
yarn add -D \
eslint babel-eslint eslint-loader \
prettier eslint-config-prettier eslint-plugin-prettier \
eslint-config-standard eslint-plugin-standard \
eslint-plugin-node \
eslint-plugin-jsx-a11y \
eslint-plugin-promise \
eslint-plugin-import \
eslint-plugin-react \
;and cp ~/.config/.eslintrc.js .
end
Though we won't dive too deep into this example, let's briefly go over what value this it brings to the workflow:
-
function yawn...
: high-level alias that acts as a cli utility to route a subcommand (passed as an argument) and call its respective internal alias -
function _install_eslint...
: internal alias that will be called fromyawn
given the input isyawn eslint
.- installs ESLint dependencies
- copies global ESLint config file
- NOTE: often times commands used internally (not directly called by the user) will be prepended with an underscore, here we utilize this nomenclature to make our
config.fish
file more readable
With these new functions you are now able to dive into a new project and call yawn eslint
to set up ESLint. Personally I use this all the time and love to automate monotonous tasks just like this example.
Final Thoughts
So far we've covered:
- Fish functions
- Editing and using the Fish dotfile:
config.fish
- Reloading the dotfile
- Using functions to shorten commands
- Using functions to extend commands
- Using functions to automate tasks
I hope I was able to convince you to start using this functionality, whether you use the examples provided or by creating your own. Speaking of, in the last example I provided the skeleton to add more subcommands to the yawn
function, try setting up your own internal function that helps automate the tedious aspects of your workflow! I'd love to hear how Fish functions have enhanced your workflow, Tweet @garlicbred with your story!
Top comments (1)
Great post about enhancing the productivity with fish!
Can't wait for your next article!