DIY: basic React component generator with Plop.js

Every React app contains components, with large projects often containing hundreds. Development with the many components, styles and tests in the proper folder can be relatively time-consuming and very repetitive.

This issue can be circumvented using the popular Nx build system and its plethora of functions. Nx is unfortunately too big for many small projects, and the vast number of possibilities can in some way be overwhelming for those who are not fluent with this tool, so the time to compile code using Nx leaves much to be desired. It should also be borne in mind that Nx customisation is limited. For those projects that don’t require such an advanced tool as Nx it is worth taking a closer look at Plop.

What is Plop?

Plop is a tool for generating code. This starts with a generator, generator script in a configuration file and a target file schema to generate. The configuration file can be freely modified, and at any time individual generators can be edited or added. One great advantage of Plop is the fact that it has a clearly defined and structured layout, and so any competent programmer will easily be able to use this tool, and editing won’t pose a challenge.

Getting started

Step #1 Plop installation

The first thing do is install plop. 

npm install -g plop

Step #2 Configuration file

The next element of plop is creating a configuration file, plopfile.js, that contains the generating functions. It should be placed in the main catalogue of the app. 

export default function (plop) {};

Now Plop can be added to the project. At this stage no functionalities have been defined yet so when the plop command is invoked from the catalogue of the app, a message that no generator has been found is displayed.   

Step #3 Adding the first generator

The next step is to build a simple generator. The demonstrated generator function takes an input-type prompt which is the name of the component. There can be multiple prompts with many input-types to choose from. A full list is available in the plop documentation. After entering the name prompt, the generator will perform an add action. Based on the template available e.g. at templates/react-components/component.hbs (which have not been built yet), it will make a new file called following the name prompt entered. 

export default function (plop) {

  plop.setGenerator('component', {

    prompts: [{

      type: 'input',

      name: 'name',

      message: 'Component name'

    }

    ],

    actions: [{

      type: 'add',

      path: 'src/components/{{name}}/{{name}}.tsx',

      templateFile: 'templates/react-components/component.hbs'

    }]

  });

};

Step #4 Creating a file template

To be able to use the generator, you need a file template. The component.hbs template is a very simple file. It uses the name prompt that will be used as the name of the component.  Handlebars (hbs) allow the use of expressions, i.e. arguments provided when invoking the generator.  

export const {{ name }} = () => {

    return (

        
{{ name }}
)};

After running Plop, selecting the only possible generator and typing the name: newFile, you get the following file in the folder src/components/exampleFile/exampleFile.tsx.

export const exampleFile = () => {

    return (

        
            exampleFile         
)};

Extra Steps

Step #5 Creating a helper function

The file generated in the previous step was built exactly as we had defined. Programmers familiar with React certainly noticed that while the file name exampleFile.tsx, depending on the adopted naming convention, is technically acceptable, the name of the react component starting with a lowercase letter is incorrect. 

Of course, you can provide the name prompt as the correct name for the component that will also be correct for the file name, i.e. ExampleFile, but in this step I would like to present the functionality of the helper – the support function for the generator. 

Let’s create a simple helper, changing the first letter of name to uppercase. 

plop.setHelper('FirstLetterCapital', (str) => {
    return str.charAt(0).toUpperCase() + str.slice(1)
  })

After adding the helper to the plop.js file

export default function (plop) {


  plop.setHelper('FirstLetterCapital', (str) => {
  	return str.charAt(0).toUpperCase() + str.slice(1)
  })


  plop.setGenerator('component', {
    prompts: [{
      type: 'input',
      name: 'name',
      message: 'Component name',
    }
    ],
    actions: [{
      type: 'add',
      path: 'src/components/{{name}}/{{name}}.tsx',
      templateFile: 'templates/react-components/component.hbs'
    }]
  })};

and including the helper function in the component.hbs file template

export const {{FirstLetterCapital name }} = () => {
    return (
        
{{ name }}
)};

the generated component named exampleFile.tsx looks as follows

export const ExampleFile = () => {
    return (
        
exampleFile
)};

Step #6 Validation

Plop enables adding validation for prompts, which can be performed through the javascript function. Validation is optional.  

plop.setGenerator('component', {

    prompts: [{

      type: 'input',

      name: 'name',

      message: 'Component name',

      validate: (value)=> ((/[a-z]/gi).test(value)) ? true : 'name is required'

    }

    ],

    actions: [{

      type: 'add',

      path: 'src/components/{{name}}/{{name}}.tsx',

      templateFile: 'templates/react-components/component.hbs'

    }]

  });

Step #7 Custom Actions

Using Plop, you can also create Custom Actions, which contain javascript functions. Below is an action that will install the Redux package using the Exec package.

plop.setActionType('Redux toolkit installation', function () {
    exec(`npm i @reduxjs/toolkit react-redux`,(error, stdout, stderr)=>{
      if (error) {
        console.error(`Error during installation @reduxjs/toolkit react-redux`);
        return;
        }
      console.log(`@reduxjs/toolkit react-redux installed`)
    });
  });

Adding this action to the generator looks as follows 

plop.setGenerator('component', {

    prompts: [{

      type: 'input',

      name: 'name',

      message: 'Component name',

      validate: (value)=> ((/[a-z]/gi).test(value)) ? true : 'name is required'

    }

    ],

    actions: [{

      type: 'add',

      path: 'src/components/{{name}}/{{name}}.tsx',

      templateFile: 'templates/react-components/component.hbs'

    },

    {

      type: 'Redux toolkit installation',

      configProp: 'available from the config param'

    }]

  });

Summary

Plop is a developer-friendly tool. Building a basic generator is relatively easy, and the value of the result is extremely beneficial in relation to the work involved. With more advanced functionalities, you can automate some processes of the app development without much effort. There are considerably more extensive tools on the market in which a generator is one of many functionalities, but not every project requires the “heavy artillery”. Plop is a very good and light alternative that can be used in any project.