DEV Community

Cover image for The Power of a Custom Component Generator in Next.js Projects
Narendra
Narendra

Posted on

The Power of a Custom Component Generator in Next.js Projects

As developers, we often find ourselves creating similar file structures repeatedly when working on React or Next.js projects. For instance, when building a reusable component, you might create the following files:

.tsx file for the component.
.test.tsx file for unit tests.
.stories.tsx file for documenting the component in Storybook.

While this structure is essential for maintainability and collaboration, creating these files manually every time can be tedious and error-prone. That’s where a Custom Component Generator comes in handy.

In this article, we’ll explore how a custom generator can:

  • Boost consistency across your project.
  • Save time during development.
  • Eliminate repetitive work by automating component scaffolding.

Why Use a Custom Component Generator?

  1. Enforce Consistency
    Having a standard file structure ensures your project is easy to navigate, especially in teams. A generator enforces this consistency by automatically creating files with the correct naming conventions and boilerplate code.

  2. Save Time
    Manual file creation eats up valuable time that could be spent writing actual business logic or debugging issues. A generator automates this, allowing you to focus on building features.

  3. Eliminate Errors
    Human error is inevitable when creating files manually. A typo in a filename or missed boilerplate code can cause unnecessary bugs. A generator ensures all files are created correctly every time.

  4. Scalability
    As your project grows, managing components becomes challenging. Using a generator ensures new components adhere to the same patterns, making the project scalable and maintainable.

Plop.js: Your Go-To Tool for File Generation
There are several tools for generating files, but Plop.js stands out because:

  • It’s lightweight and easy to set up.
  • It integrates well with JavaScript/TypeScript projects.
  • It supports templating with Handlebars, making it flexible.

Build a Custom Component Generator

Step 1: Install Plop.js
Add Plop.js as a development dependency:
npm install --save-dev plop

Step 2: Define a Generator in plopfile.js
Create a plopfile.js at the root of your project. This file defines how the generator works. For example:

module.exports = function (plop) {
    plop.setGenerator('component', {
        description: 'Generate a React component with TSX, test, and Storybook files',
        prompts: [
            {
                type: 'input',
                name: 'name',
                message: 'Enter the component name:',
            },
        ],
        actions: [
            {
                type: 'add',
                path: 'src/components/{{pascalCase name}}/{{pascalCase name}}.tsx',
                templateFile: 'plop-templates/component.tsx.hbs',
            },
            {
                type: 'add',
                path: 'src/components/{{pascalCase name}}/{{pascalCase name}}.test.tsx',
                templateFile: 'plop-templates/component.test.tsx.hbs',
            },
            {
                type: 'add',
                path: 'src/components/{{pascalCase name}}/{{pascalCase name}}.stories.tsx',
                templateFile: 'plop-templates/component.stories.tsx.hbs',
            },
        ],
    });
};

Enter fullscreen mode Exit fullscreen mode

Step 3: Create Templates
Create a directory plop-templates at the root of your project. Inside, add templates for the component, test, and story files:

Component Template (component.tsx.hbs):

import React from 'react';

interface {{pascalCase name}}Props {
    // Define your props here
}

const {{pascalCase name}}: React.FC<{{pascalCase name}}Props> = (props) => {
    return <div>{{pascalCase name}} works!</div>;
};

export default {{pascalCase name}};

Enter fullscreen mode Exit fullscreen mode

Test Template (component.test.tsx.hbs):

import React from 'react';
import { render, screen } from '@testing-library/react';
import {{pascalCase name}} from './{{pascalCase name}}';

describe('{{pascalCase name}}', () => {
    it('renders without crashing', () => {
        render(<{{pascalCase name}} />);
        expect(screen.getByText('{{pascalCase name}} works!')).toBeInTheDocument();
    });
});

Enter fullscreen mode Exit fullscreen mode

Storybook Template (component.stories.tsx.hbs):

import React from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';

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

export default {
    title: 'Components/{{pascalCase name}}',
    component: {{pascalCase name}},
} as ComponentMeta<typeof {{pascalCase name}}>;

const Template: ComponentStory<typeof {{pascalCase name}}> = (args) => <{{pascalCase name}} {...args} />;

export const Default = Template.bind({});
Default.args = {};

Enter fullscreen mode Exit fullscreen mode

Step 4: Run the Generator

Run the following command to generate a component:
npx plop component
You’ll be prompted to enter the component name. For example, if you type Button, the following files will be created:

src/components/Button/Button.tsx
src/components/Button/Button.test.tsx
src/components/Button/Button.stories.tsx
Enter fullscreen mode Exit fullscreen mode

Step 5: Automate with NPM Scripts
To make the process even easier, add an npm script to your package.json:

"scripts": {
    "generate": "plop component"
}

Enter fullscreen mode Exit fullscreen mode

Now, you can run the generator with:

npm run generate

Enter fullscreen mode Exit fullscreen mode

Extending the Generator

Plop.js is highly flexible. Here are some ways you can extend it:

  • 1. Add Custom Prompts: Ask for additional details like component props or folder structure.
  • 2. Support Style Files: Automatically generate a .module.css or .scss file for the component.
  • 3. Set Up with Context/Redux: Include boilerplate for managing state.
  • 4. Preconfigure Dependencies: Add imports for common libraries like Material UI, Tailwind CSS, or custom hooks.

Key Benefits of Using a Custom Component Generator

  1. Team Alignment
    A generator enforces your team’s coding standards. New team members can quickly adapt to the project structure, reducing onboarding time.

  2. Scalability
    As your project grows, maintaining consistency across hundreds of components becomes easy.

  3. Productivity
    Focus on solving complex problems instead of setting up boilerplate files.

  4. Maintainability
    Standardized components are easier to test, debug, and extend.

Conclusion
A custom component generator is a small but powerful addition to your workflow that can make a big impact on your productivity and project quality. By leveraging tools like Plop.js, you can enforce standards, save time, and ensure scalability across your Next.js projects.

So why not try it out in your project today? Happy coding! 🎉

Got ideas or questions? Let me know in the comments. And if you found this post helpful, share it with your fellow developers! 🚀

Top comments (0)