How to
Software development
Written by
Alex Harvey
Date
3 years ago
Read time
4 minutes
When we’re working on a project for a client, the speed at which we work is crucial as to adhere to the principles of agile development, get features out to customers quickly and increase team confidence and satisfaction.
There are many tools that help us set up a project quickly when first getting started - Create React App, Gatsby starters, etc. - but is there a tool that we can use that will speed up the process of creating new React components? More specifically, is there a way we can generate component files, test files, Storybook files and index files all via one command? The answer is yes and the solution is a tool called hygen
.
As detailed on the project’s Github, hygen
is the simple, fast, and scalable code generator that lives in your project. Hygen
allows us to create JavaScript files from templates. The cool thing about hygen
is it’s completely customisable, so no matter the style guide/linting rules/code standards you follow, you can make it work for you.
Before we get started, it’s worth mentioning that we are using atomic design to structure our component library and Storybook to build and view our components in different states.
Atomic design is a methodology used for building design systems using an explicit order and component hierarchy. It’s implemented by breaking components down into their smallest elements, then combining these elements to make complex structures. Components are placed in one of five categories:
Atoms
Molecules
Organisms
Templates
Pages
Atomic design is great because it encourages reusability, allows components to be developed in isolation, gives us a more modular file structure and makes our layout easier to understand. Read more about it here.
Storybook is a tool that provides us with a sandbox environment for building components and pages in isolation.
Let’s look at how we add hygen
to a project. We’ll start by creating a new Typescript project using create-react-app
:
npx create-react-app my-app --template typescript
Next, we’ll add and initialise Storybook in Typescript:
cd my-app npx -p @storybook/cli sb init --story-format=csf-ts
Now let’s install hygen
as well as a few other dependencies:
yarn add hygen @storybook/react react-test-renderer @types/react-test-renderer -D
Our next step is to add some files. First we need to add the folders _templates
, component
and with-prompt
:
mkdir -p _templates/component/with-prompt
We now want to create a couple of files inside the with-prompt
folder. The first is core_index.ejs.t
, which is going to add to our top level index.ts
file inside the components
folder:
--- inject: true append: true to: src/components/index.ts --- export * from './<%=name%>';
What’s going on here? This is an EJS template. The first part of the file is frontmatter. The inject: true
is telling hygen
to inject into an already existing file. The append: true
is telling hygen
to add this to the end of the file. And the to: src/components/index.ts
is telling hygen
what file to inject into.
The second part of this file is simply the content we want to inject into the file. Notice we have used <%=name%>
to name the component, which is standard EJS syntax telling hygen
that the name of the component is going to be passed in when we run the command (which we’ll see later).
Now let’s add a core.ejs.t
inside the with-prompt
folder, which will be the template of the component we create:
--- to: src/components/<%=name%>/<%=name%>.tsx --- import React, { FC } from 'react'; interface Props {} export const <%=name%>: FC<Props> = (props) => <div {...props} />;
Here we are creating a new component in its own directory within the components folder. The actual template is a little more extensive than before, but it follows exactly the same principles as we’ve previously seen.
In a similar fashion, we can create template files for the index of each component, as well as test files and Storybook files.
index.ejs.t
:
--- to: src/components/<%=name%>/index.ts --- export * from './<%=name%>';
story.ejs.t
:
--- to: src/components/<%=name%>/<%=name%>.stories.tsx --- import React, { ComponentProps } from 'react'; import { Story } from '@storybook/react/types-6-0'; import { <%=name%> } from './<%=name%>'; const Template: Story<ComponentProps<typeof <%=name%>>> = (args) => ( <<%=name%> {...args} /> ); export const Basic = Template.bind({}); Basic.args = {}; export default { component: <%=name%>, title: '<%=name%>', };
test.ejs.t
:
--- to: src/components/<%=name%>/<%=name%>.test.tsx --- import React from 'react'; import { render } from '@testing-library/react'; import renderer from 'react-test-renderer'; import { <%=name%> } from './<%=name%>'; describe('<%=name%>', () => { it('should render', () => { render(<<%=name%> />); }); it('should match a snapshot', () => { const tree = renderer.create(<<%=name%> />).toJSON(); expect(tree).toMatchSnapshot(); }); });
The last file we need to add inside the with-prompt
folder is the prompt.js
file. This is where we will get the name of the component from the user by prompting them to type it in:
module.exports = [ { type: 'input', name: 'name', message: "What's the name of your component?" }, ];
Let’s add a couple of lines to our package.json
inside the "scripts"
object so that we can generate our components with Hygen and also so we can easily start Storybook:
"component": "HYGEN_TMPLS=scripts/_templates yarn hygen component with-prompt", "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook"
Now create a folder called components inside the src
directory and add a file called index.ts
:
mkdir src/components touch src/components/index.ts
We’re now ready to create a component. Input the following command into your terminal:
yarn component
You’ll be prompted to enter the name of your component. Call your component Test
by typing that into the terminal and hitting enter, and you’ll see that hygen
creates files for each of the templates we created above, as well as appending the export to the end of the index.ts
file in the components
folder:
Pretty sweet, right? We can actually skip the prompt altogether by typing in the name of the component at the end of the command, i.e.
yarn component Test
You can modify and extend these templates to fit whatever suits your needs. Here at Contic, we use hygen
to enforce an atomic design structure in our code. Hopefully this has some use for you in your future projects. Happy coding!
Subscribe to our newsletter
Be the first to know about our latest updates, industry trends, and expert insights
Your may unsubscribe from these communications at any time. For information please review our privacy policy.