DEV Community

Akhil
Akhil

Posted on • Originally published at akhilgautam.me

Generate React Components using commands from your terminal

Let's first talk about the problem statement.

Your frontend application Fatebook 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
Enter fullscreen mode Exit fullscreen mode
  • Plop.js uses plopfile to perform actions.
  • add, modify, and append 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 handlebar template or templateFile.

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, and message. Internally plopjs uses https://github.com/SBoudrias/Inquirer.js/#question for executing prompts.
  • 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';",
    },
  ],
};
Enter fullscreen mode Exit fullscreen mode

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);
};
Enter fullscreen mode Exit fullscreen mode

Now, let's add a script in package.json to run the plops.

"scripts": {
  ...
  "generate": "plop"
  },
Enter fullscreen mode Exit fullscreen mode

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.

Screenshot 2021-09-28 at 6.07.19 PM.png

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);
};
Enter fullscreen mode Exit fullscreen mode

Now, when I run npm run generate, I get the following:

Screenshot 2021-09-28 at 6.13.08 PM.png

Thanks for reading till the end. I hope people go through plop.js and create stunning automations and share them with the community.

Discussion (0)