DEV Community

Cover image for How to generate automatically components/ pages/hooks on your code with PlopJS.
Vicky V
Vicky V

Posted on • Updated on

How to generate automatically components/ pages/hooks on your code with PlopJS.

Have you ever wished a way to generate the 'about' component, the 'home' component, the 'projects' component or any component, page, hook, icon, that has the same structure without repeating yourself over and over?

I didnt know that this amazing tool existed but I am so happy to share it with you and I hope it will bring you joy as it did to me.

The following example is to generate automatically components. If you want to create hook you need to create new folders and files as explained for the component example.

Here the plopJS comes to offer.
They call it "micro-generator framework."
https://github.com/plopjs/plop.

I am using TypeScript and NextJS for this project.

Installation

$ npm install --save-dev plop

Create a plopfile.js at the root of your project

const generateComponent = require('./generate/component');
const generateIcon = require('./generate/icon');
const generatePage = require('./generate/page');

module.exports = function (plop) {
  plop.setGenerator('component', generateComponent);
  plop.setGenerator('icon', generateIcon);
  plop.setGenerator('page', generatePage);
};
Enter fullscreen mode Exit fullscreen mode

On your package.json

"new": "plop",
    "new:component": "plop component",
    "new:page": "plop page",
    "new:icon": "plop icon"
Enter fullscreen mode Exit fullscreen mode

Create a folder at the root of your project named generate and inside another folder called component. Inside that folder create another folder called templates and a file name index.js`` (this file is outside of templates and inside component folder.).

Image description

Image description

Image description

For index.js

This index.js is the one you see above on the picture.

``

module.exports = {
  description: 'Generates new React component',
  prompts: [
    {
      type: 'input',
      name: 'name',
      message: "What's the name of the Component?",
      validate: function (value) {
        let message = true
        if (!/.+/.test(value)) {
          message = console.error('Missing', 'you must define a component name')
        } else if (value.length < 3) {
          message = console.error(
            'Too Short',
            `"${value}" is not descriptive enough`,
          )
        }
        return message
      },
    },
  ],
  actions: function () {
    return [
      {
        type: 'add',
        path: 'src/components/{{pascalCase name}}/{{pascalCase name}}.tsx',
        templateFile: './generate/component/templates/component.hbs',
      },

      {
        type: 'add',
        path: 'src/components/{{pascalCase name}}/{{pascalCase name}}.docs.mdx',
        templateFile: './generate/component/templates/docs.hbs',
      },
    ]
  },
}

Enter fullscreen mode Exit fullscreen mode


``

Then inside the templates folder create a file named component.hbs. You can customise as much as you want your component.

``

import React, { ReactNode } from 'react'
import { Box } from 'theme-ui'; export

interface {{pascalCase name}}Props { children: ReactNode }```

``

``

```js

export const {{pascalCase name}} = ({ children }: {{pascalCasename}}Props): JSX.Element => { 
 return (
<Box>
  <Box>{{name}}</Box>
</Box>
 )}

Enter fullscreen mode Exit fullscreen mode


``

Again in the same folder you can add a file named docs.hbs

``

import { Story, Canvas } from '@storybook/addon-docs/blocks'
import { {{pascalCase name}} } from './{{pascalCase name}}'

{{pascalCase name}}. Give a description of what the component does

import { {{pascalCase name}} } from './components'

<{{pascalCase name}}>Some content</{{pascalCase name}}>
Enter fullscreen mode Exit fullscreen mode


``

Now run the command and you should be able to see this:

new

The same process is if you want to create a page, a hook or icons.

Discussion (4)

Collapse
websnake profile image
Doug Snyder

I thought the topic was interesting and wopudl give me a fsrt way to explore plopjs. I started following your instructions and then found that you expect my to copy like 20 lines of code from an image file for index.js instead copying from a tag or github repo. I realized this wasn't a short cut to learning plop and abondoned the tutorial having wasted time setting up a project already. I suggest you either share code in a way that is sharteable or mention somewhere upfron that this is not a tutorial where you'll be able to replicate ... but only to read.

Collapse
vikirobles profile image
Vicky V Author

I think now is much better and I hope you can use it

Collapse
vikirobles profile image
Vicky V Author

I tried to share the code and sometimes half of the lines would be in a way to copy the code and half would look bad so I decided to share the pictures. Thank you for mentioning it will do.

Collapse
mrmartineau profile image
Zander Martineau

Awesome post! Can you edit to add real code blocks instead of images? I'd like to be able to use them in my project 😁