Short Scripts for Small Wins
Improve the Developer Experience with this Quick Tip
Table of contents
A Note on the Series:
Fast Fridays π is a series where you will find fast, short, and sweet tips/hacks that you may or may not be aware of. I will try to provide these (fairly) regularly on Fridays.
In this Fast Friday tip, Iβll cover a short bash script I created that has allowed me to start developing new components within our reports library in seconds instead of minutes. Iβm always looking for little hacks I can employ to help improve my productivity as a developer and I hope this helps you as well!
The Friction Point
Throughout my career, Iβve maintained a few component libraries and there has been a common procedure that Iβve had to follow in each of them.
Step 1: Create a folder and corresponding
*.jsx
or*.tsx
file for housing React component X.Step 2: Create a styles file for component X.
Step 3: Create Storybook files for component X.
Step 4: Create a tests folder and files for component X.
Step 5: Forget all the boilerplate that you have to add for steps 1 -4 that this process takes longer than it should and ends up being annoying π£
One day, while going through this monotonous cycle, I thought, "There has to be a better way to do this." I got so frustrated with the process that I finally decided to do something about it.
The Solution
After thinking about the problem for a bit, I decided I would tinker with creating a bash script to help automate these steps. I had only ever written a handful of bash scripts, so this gave me a good opportunity to learn more about developing in bash.
My development workflow for this was fairly straightforward, I took steps 1- 4 that I outlined in the previous section, turned those into bash commands, and then filled in any missing gaps.
Here's the final code:
#!/usr/bin/env bash
# Prompt for component name
read -p "Enter component name: " COMPONENT_NAME
TOP_LEVEL_DIR="src/components/$COMPONENT_NAME"
# Check if folder already exists. If it does, abort the process.
if [ -d "$TOP_LEVEL_DIR" ]; then
echo "Folder already exists so aborting the process..."
exit 1
fi
# Create a new directory for the component
mkdir -p "$TOP_LEVEL_DIR"
echo "π Created new directory: /$COMPONENT_NAME"
# Create component file
COMPONENT_FILEPATH="$TOP_LEVEL_DIR/$COMPONENT_NAME.tsx"
printf "%s" "import React from 'react';
import { StyledH1 } from './$COMPONENT_NAME.styled';
export default function $COMPONENT_NAME(): JSX.Element {
return <StyledH1>New $COMPONENT_NAME Component</StyledH1>;
}
" > "$COMPONENT_FILEPATH"
echo "π Created $COMPONENT_NAME.tsx"
# Create styled component file
SC_FILEPATH="$TOP_LEVEL_DIR/$COMPONENT_NAME.styled.ts"
printf "%s" "import styled from 'styled-components';
import { color } from '@/styles/variables';
export const StyledH1 = styled.h1\`
color: \${color.blue[700].value};
\`;
" > "$SC_FILEPATH"
echo "π Created $COMPONENT_NAME.styled.ts file"
# Create stories file
STORIES_FILEPATH="$TOP_LEVEL_DIR/$COMPONENT_NAME.stories.tsx"
printf "%s" "import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import $COMPONENT_NAME from './$COMPONENT_NAME';
export default {
title: 'Components/$COMPONENT_NAME',
component: $COMPONENT_NAME,
parameters: {
design: {
type: 'figma',
url: '',
},
},
} as ComponentMeta<typeof $COMPONENT_NAME>;
const Template: ComponentStory<typeof $COMPONENT_NAME> = (args) => <$COMPONENT_NAME {...args} />;
export const Default = Template.bind({});
Default.args = {};
" > "$STORIES_FILEPATH"
echo "π Created $COMPONENT_NAME.stories.tsx"
# Create test folder and file
TEST_FILEPATH="$TOP_LEVEL_DIR/__tests__/$COMPONENT_NAME.test.tsx"
mkdir -p "$TOP_LEVEL_DIR/__tests__"
echo "π Created __tests__ folder"
printf "%s" "import React from 'react';
import { render, screen } from '@testing-library/react';
import $COMPONENT_NAME from '../$COMPONENT_NAME';
describe('$COMPONENT_NAME Component', () => {
test('renders default view', () => {
render(<$COMPONENT_NAME />);
});
});
" > "$TEST_FILEPATH"
echo "π Created $COMPONENT_NAME.test.tsx"
Now, all you have to do to create a new component is run the command. You will be prompted to name the new component, and the script will handle creating a new folder with all the necessary files, folders, and boilerplate code.
Measurable Improvements
Whenever I take time away from my assigned tasks to implement things like this, I try to think about the measurable improvements that were made. Here are a few reasons why I believe it was time well spent:
There is now a streamlined process for a repeatable task. Automation works best in these situations, making this the perfect task for a script.
Before, adding all the boilerplate for a new component would probably take around 5 minutes. Now, the time was reduced to just a few seconds.
Having an automated process for creating new components ensured code consistency in terms of file structure and organization.
To make this process even simpler, I added an npm script to the projects
package.json
file so that any developer on the team could easily run this script by runningyarn:new component
in their terminal.
El Fin ππ½
Overall, It was cool that a bash script of less than 100 lines of code could speed up my development process considerably. The next time you have a friction point when developing, consider if thereβs a way that you can automate the process.
If you enjoy what you read, feel free to like this article or subscribe to my newsletter, where I write about programming and productivity tips.
As always, thank you for reading, and happy coding!