Create react components at the speed of light with Plop.js

Use plop.js to make the tedious task of creating new files a breeze

So you are working in your React app, and it comes the time to create a new component, you already have your ritual down. Go to the components folder, create an index file, create another file for styles and finally one more for testing because you are cool. After all of this, you still have to connect these files and write enough code to make them run. You do this every time... every time.

Boring task

I am assuming a lot, but if this is actually you I have good news! What if I told you there is way to automate this boring and tedious process? Trust me, these next 10 minutes are going to change your life. Let me introduce you to plop.js

What is Plop.js?

In their own words, it's a tool that saves you time and helps you build new files with consistency.

How does it work?

It's easier than you think, otherwise I wouldn't be writing about it lol. You create file templates and configure a very simple cli.

Let's start

First, let's clone this simple react app, it has nothing but just a basic react setup.

git clone git@github.com:ivanms1/parcel-template.git

And navigate to it

cd parcel-template

Now let's install plop on the terminal type:

yarn add plop
# or
npm install plop

The Generator

Next, on the root folder, create a file called plopfile.js and add the following content inside.

module.exports = function (plop) {
  plop.setGenerator("component", {
    description: "Create a component",
    prompts: [
      {
        type: "input",
        name: "name",
        message: "What is this component's name?",
      },
      {
        type: "input",
        name: "element",
        message: "HTML element (div is default)",
        default: "div",
      },
    ],
    actions: [
      {
        type: "add",
        path: "src/components/{{pascalCase name}}/{{pascalCase name}}.tsx",
        templateFile: "templates/Component.tsx.hbs",
      },
    ],
  });
};

We are basically configuring a cli to generate our files. plop.setGenerator creates a generator, the first argument is the name of this generator and the second one is an object with some options where we can configure what to generate. Let's analyze the ones we will be using for this guide.

description

Pretty self explanatory, a description of your generator, for example: Generator of react components.

prompts

Series of steps, questions or instructions we give to the user in order to obtain certain information. Plop stores these in variables to use later in the template files. In our case we are using input type prompts to get

  • The component's name.
  • The component's html tag (div, button, a, etc), it defaults to div.

message is text the user will see and has to interact with, generally a question or an instruction.

actions

After we've gather all the information need we then proceed to the actions, represented in an array. In our case we only have one action that creates a file.

Let's go a bit into more details with the actions, since it's where things actually happen. The add action type creates a file, path is simply the file path where the file is going to be created. The template is sort of skeleton that will be used to create the file. Plop uses handlebars, a templating language that generates HTML and other text formats.

You might have noticed that we haven't created our template file, and yeah... we need to do that.

Creating our first template

On the root folder create a folder called templates, and add a file named Component.tsx.hbs with the following content.

import React from "react";

interface {{pascalCase name}}Props {}

const {{pascalCase name}} = () => {
  return <div>{{pascalCase name}}</div>;
};

export default {{pascalCase name}};

As you could probably tell, we are creating a react typescript file, in handlebars the variables are inside double brackets ({{}}). pascalCase converts the name variable, that we get from the prompts, to pascal case. So anywhere you see {{pascalCase name}}, it will be replaced with the component's name.

So although this is cool, so far we are only creating a new file with some pre-written react code. There are snippet extensions that could do almost the same thing. Let's make this a bit more complete by also adding a style file.

Adding a style file

I am gonna be using stitches, a css-in-js library similar to styled components but with near-zero runtime, but feel free to use whatever you want.

Let's install the library first, on the terminal run:

yarn add @stitches/react
# or
npm install @stitches/react

Since we now want to create a style file as well, we need to add another action to our generator. Update plopfile.js with the following.

    actions: [
      {
        type: "add",
        path: "src/components/{{pascalCase name}}/{{pascalCase name}}.tsx",
        templateFile: "templates/Component.tsx.hbs",
      },
      // new action here
      {
        type: "add",
        path: "src/components/{{pascalCase name}}/styles.ts",
        templateFile: "templates/styles.ts.hbs",
      },
    ],

Pretty similar to the first action, now we need to add a new template. Inside the templates folder create a file called styles.ts.hbs and add the following content.

import { styled } from '@stitches/react';

export const Styled{{pascalCase name}} = styled('{{element}}', {});

Just your basic css-in-js file, we create a styled component and export it.

Component.tsx.hbs needs to be updated, so it imports and uses the new styled component we made. Now it should look like this:

import React from "react";

import { Styled{{pascalCase name}} } from "./styles";

interface {{pascalCase name}}Props {}

const {{pascalCase name}} = ({} : {{pascalCase name}}Props) => {
  return <Styled{{pascalCase name}}>{{pascalCase name}}</Styled{{pascalCase name}}>;
};

export default {{pascalCase name}};

Now we are talking, plop is saving us some considerable time, generating not one, but two files.

The final step to see this in action is to add the following script to the package.json.

  "scripts": {
    ..., // rest of scripts
    // add this at the end
    "generate": "plop"
  },

We are finally ready, sit down, relax and enjoy the show. On the terminal type

yarn generate
# or
npm run generate

Now let's create a Button component.

Give component a name

With a button tag of course.

Give component a tag

If everything went well

Success

Let's check the components folder.

import React from "react";

import { StyledButton } from "./styles";

interface ButtonProps {}

const Button = ({} : ButtonProps) => {
  return <StyledButton>Button</StyledButton>;
};

export default Button;

The styles file is there as well.

import { styled } from '@stitches/react';

export const StyledButton = styled('button', {});

Cat surprised

Pretty cool eh?

Ok maybe is not that cool, but hopefully by now you've realized the potential this has.

I've kept this simple and only created two files but you can keep playing with it and add as many generators and actions as you want. All people/teams are different and you can tweak plop to whatever convention/style you may have. You can even update existing files if for example you like having an index file for all your components. You can create generators for hooks, pages, helpers, etc, the sky is the limit.

I hope you liked this guide and let me know if you made any cool generators at @ivanms1

Thank you for taking the time to read this article, if you enjoyed it please like to support and follow for more.

Source Code