Short Scripts for Small Wins

Short Scripts for Small Wins

Improve the Developer Experience with this Quick Tip

Β·

4 min read

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:

  1. There is now a streamlined process for a repeatable task. Automation works best in these situations, making this the perfect task for a script.

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

  3. Having an automated process for creating new components ensured code consistency in terms of file structure and organization.

  4. 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 running yarn:new component in their terminal.

Terminal output after running the bash script

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!