Are you creating React components like this
Create React components with just one command
Let's first talk about the problem statement.
Your frontend application Hashlink has become huge. You have been following a specific set of patterns to put all the components, pages, shared libraries, etc., in specific directories. Now it is time to hire people but you want to enforce them to follow the same. One way could be a well-documented instruction that they will be given on day 1 and they will be asked to adhere to it.
Another better way would be to create generators which would automatically create new components at specified directories.
Solution
In this blog, we will see the basic use of plopfile generators to create Skeletal React components based on their type from the terminal.
Install plop.js as dev dependency of your React project:
$ npm install --save-dev plop
- Plop.js uses
plopfile
to perform actions. add
,modify
, andappend
are a few of the most commonly used actions.- We can use the
add
action to create components based on a template. For templating,plop.js
uses handlebartemplate
ortemplateFile
.
Create a generator that creates a component under the src/shared_components
directory.
- a generator consists of
prompts
&actions
. - prompts are used to gather user data. It mainly consists of three properties
type
,name
, andmessage
. Internallyplopjs
uses https://github.com/SBoudrias/Inquirer.js/#question for executingprompts
. - actions are used to perform actions of a specific
type
based on the template provided to it.
// generators/shared_component/Component.jsx.hbs
import React from "react";
const {{properCase name}} = (props) => {
return <div>{{properCase name}}</div>;
};
export default {{properCase name}};
// generators/shared_component/index.js
module.exports = {
description: 'Create a shared component',
prompts: [
{
type: 'input',
name: 'name',
message: 'component name(required):',
},
],
actions: [
{
type: 'add',
path: 'src/components/shared/{{properCase name}}.jsx',
templateFile: 'generators/shared_component/Component.jsx.hbs',
},
{
type: 'append',
path: 'src/components/shared/index.js',
template:
"export { default as {{properCase name}} } from './{{properCase name}}.jsx';",
},
],
};
We have created a generators
directory at the root of the React project. Inside that, we have two files, one is the template file written with handlebars and another file is the generator itself that contains actions and prompts.
Now we can create a plopfile.js
at the root level and import the generator created above to use them.
// plopfile.js
const sharedComponentGenerator = require('./generators/shared_component/index');
module.exports = function (plop) {
plop.setGenerator('shared component', sharedComponentGenerator);
};
Now, let's add a script in package.json
to run the plops.
"scripts": {
...
"generate": "plop"
},
That's it. We can go to our terminal and run npm run generate
and it will show the prompt to create the shared components.
Bonus:
I currently use 3 generators, shared_component, component, and page. Below is the code for it:
// generators/component/Component.jsx.hbs
import React from "react";
const {{properCase name}} = (props) => {
return <div>{{properCase name}}</div>;
};
export default {{properCase name}};
// generators/component/index.js
module.exports = {
description: 'Create a component',
prompts: [
{
type: 'input',
name: 'name',
message: 'component name(required):',
},
{
type: 'input',
name: 'folder',
message: 'which folder in /src/components (default is /src/components):',
},
],
actions: [
{
type: 'add',
path: 'src/components/{{folder}}/{{properCase name}}.jsx',
templateFile: 'generators/component/Component.jsx.hbs',
},
],
};
// generators/page/Page.jsx.hbs
import React from "react";
const {{properCase name}} = (props) => {
return <div>{{properCase name}}</div>;
};
export default {{properCase name}};
// generators/page/index.js
module.exports = {
description: 'Create a page',
prompts: [
{
type: 'input',
name: 'name',
message: 'page name(required):',
},
],
actions: [
{
type: 'add',
path: 'src/pages/{{properCase name}}.jsx',
templateFile: 'generators/page/Page.jsx.hbs',
},
],
};
// plopfile.js
const componentGenerator = require('./generators/component/index');
const sharedComponentGenerator = require('./generators/shared_component/index');
const pageGenerator = require('./generators/page/index');
module.exports = function (plop) {
plop.setGenerator('component', componentGenerator);
plop.setGenerator('shared component', sharedComponentGenerator);
plop.setGenerator('page', pageGenerator);
};
Now, when I run npm run generate
, I get the following:
Thanks for reading till the end. I hope people go through plop.js
and create stunning automations and share them with the community.