DEV Community

Cover image for Automate components creation in React project
Rafael Leitão
Rafael Leitão

Posted on

Automate components creation in React project

We write code and create files every day. If you're developing some frontend project most likely you're creating components which start with almost the same folder and file structures. Creating this over and over again is a boring job and one that most of us probably would love to improve.

I was facing that in a React project I'm currently working on and I wanted to automate these initial files every time I wanted to create a component. For that, there is a Javascript called Plop.

What is Plop.js?

As in its website, Plop is a little tool that saves you time and helps your team build new files with consistency. It makes our life easier when creating files because we just need to setup, create some generators and templates and from that every new files created will follow the same structure.

How to use it?

1. Installation

npm install --save-dev plop
yarn add -D plop
Enter fullscreen mode Exit fullscreen mode

2. Create a Plop file

A Plop file is where we create generators for the library to execute when we run plop command in terminal.

It is a file where we basically export a function which receives the plop object. This object exposes the Plop API which then we can create a generator with the setGenerator(name, config) function.

A generator is where we define the prompts, questions to be asked to the user, and the actions, to be performed by Plop for adding, modifying or appending files.

An example taken from the docs for a basic plop file in Javascript:

// plopfile.js
module.exports = function (plop) {
    // controller generator
    plop.setGenerator('controller', {
        description: 'application controller logic',
        prompts: [{
            type: 'input',
            name: 'name',
            message: 'controller name please'
        }],
        actions: [{
            type: 'add',
            path: 'src/{{name}}.js',
            templateFile: 'plop-templates/controller.hbs'
        }]
    });
};
Enter fullscreen mode Exit fullscreen mode

This generator called controller will ask us for the controller name and will perform a creation of file in the specified path with a dynamic file name and this new file will be structured the same way as controller.hbs file.

3. Create a template file with Handlebars

Handlebars is a templating language, it uses a (wait for it) template with an input object to generate HTML or other text formats. It looks like normal text with some Handlebars expressions. We won't cover more than this, this is the basic stuff to get going here, but you can dive deep in the docs.

With this template defined the generator will do its actions and create the files for us. Let's see an example in action.

Real usage example

I hope the steps above were enough to understand the basic follow. In this section we'll see a real example, the way I used Plop for my current project.

1. Creating a Plopfile

For my current project I'm using Atomic Design to structure my components as a way to improve its consistency and reusability.

For each component I create I need to define which folder it is going to be added to, besides its name. These are the prompts my generator has.

Furthermore, I usually create a 3 files for each component: index.tsx for the component itself, stories.tsx for the Storybook stories and test.tsx for the tests. In this example, to simplify, I'm creating only the first two. So, these are my actions for the generator.

import {NodePlopAPI} from 'plop';

export default function (plop: NodePlopAPI) {
    // controller generator
    plop.setGenerator('component', {
        description: 'Atomic Design component creation logic',
        prompts: [
          {
            type: 'input',
            name: 'name',
            message: 'Component name please',
          },
          {
            type: 'input',
            name: 'level',
            message: 'Atomic Design level of the component please',
          },
        ],
        actions: [
          {
            type: 'add',
            path: '../src/components/{{level}}/{{pascalCase name}}/index.tsx',
            templateFile: 'templates/index.tsx.hbs',
          },
          {
            type: 'add',
            path: '../src/components/{{level}}/{{pascalCase name}}/stories.tsx',
            templateFile: 'templates/stories.tsx.hbs',
          }
        ],
      })
}
Enter fullscreen mode Exit fullscreen mode

Bear in mind that the export is a little different from the previous I showed since I'm using Typescript for my project.

So, basically this generator prompts questions for me and according to my answers it creates two files in a dynamically created folder based on the templates.

2. Creating the templates

For the templates I created two Handlebars files, one for stories.tsx and other for index.tsx.

1. index.tsx

import { Box } from '@chakra-ui/react'

export type {{pascalCase name}}Props = {

}

const {{pascalCase name}} = ({ }: {{pascalCase name}}Props) => (
  <Box>
    {{pascalCase name}}
  </Box>
)

export default {{pascalCase name}}
Enter fullscreen mode Exit fullscreen mode

2. stories.tsx

import {{pascalCase name}}, { {{pascalCase name}}Props } from '.'
import { Story, Meta } from '@storybook/react'

export default {
  title: '{{pascalCase name}}',
  component: {{pascalCase name}},
} as Meta

const Template: Story<{{pascalCase name}}Props> = (args) => <{{pascalCase name}} {...args} />

export const Default = Template.bind({})
Default.args = {

}
Enter fullscreen mode Exit fullscreen mode

In each template file, the {{pascalCase name}} will be replaced by the name, as a pascal case string, I provided when running plop command.

3. Run the plop command in a package.json script

To make it easier for me, I created a script called generate to run the plop command, the --plopfile flag is used to direct the path to my plopfile with the generator.

// package.json
// ...
  "scripts": {
    //...
    "generate": "yarn plop --plopfile ./plop/plopfile.ts"
  },
// ...
Enter fullscreen mode Exit fullscreen mode

When runing yarn generate, Plop will ask me the questions I defined and create the files accordingly as seen below:

Plop execution

Generated index.tsx:

import { Box } from '@chakra-ui/react'

export type UserHeaderProps = {

}

const UserHeader = ({ }: UserHeaderProps) => (
  <Box>
    UserHeader
  </Box>
)

export default UserHeader
Enter fullscreen mode Exit fullscreen mode

Conclusion

That's it! You just need to set up Plop and follow the steps to create its generator in the plop file, the templates files and the script to run it. After that, from a simple script call, Plop will do everything for you to make it smoother when creating new components for you application.

Plop can do much more than this and I encourage you to check its docs. For now, this has already made my life easier and I hope it can also help you.

If it was somehow useful, leave it a ❤️ or if you have more to add drop a comment. Also, I'd love if we connect on Twitter as well :)

Discussion (0)