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);
};
On your package.json
"new": "plop",
"new:component": "plop component",
"new:page": "plop page",
"new:icon": "plop icon"
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.).
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',
},
]
},
}
``
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>
)}
``
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}}>
``
Now run the command and you should be able to see this:
The same process is if you want to create a page, a hook or icons.
Top comments (4)
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.
I think now is much better and I hope you can use it
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.
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 😁