I plan to build a series of SaaS apps. Those apps will share some common UI features (signup, login, etc.). To avoid having to cut and paste code, I’m going to put all the common elements into reusable components. To do that, I need to generate a bunch of React component projects.

Create a Component

I wrote a bunch of shell scripts to create a React component project. Then I decided to turn those scripts into a Yeoman generator. There are other component project generators out there. But I wanted something I could own and customize. That’s because I plan to build a lot of components.

You can find instructions for installing and using my generator here:

Here is how you can install my generator (leave out sudo if not required):

$ sudo npm install -g yo
$ sudo npm install -g generator-mitchallen-react-component

The generator creates a simple test suite and runs it as a sanity check after creating the component. It uses a tool called jest that should be installed first:

$ sudo npm install -g jest jest-cli

To create a React component project, do the following and just answer the prompts:

$ mkdir my-component
$ cd my-component
$ yo mitchallen-react-component

Below is an example of the prompts and my answers. To follow along, adjust for your own accounts:

Note: As of 0.0.35 the generator now prompts for a Circle CI user name instead of a Travis CI user name. This was due to issues running webpack on Travis CI.

? Will this project be published under an npm scope? Yes
? npm scope name: mitchallen
? npm package name: my-component
? react component class name (Capitalize, no dashes): MyComponent
? bitbucket.org user name: mitchallen
? github.com user name: mitchallen
? circleci.com user name: mitchallen
? codecov.io user name: mitchallen
? npm author name: Mitch Allen

When done, a new component will be generated in the folder where the generator was run.

Scope

By saying “Yes” to the scope question, the generator created an npm project name containing my scope name in package.json:

"name": "@mitchallen/my-component",

I used my username because on npmjs.com your scope name is your username.

The package can still be public when published, but under a scope name.

Git Integration

The generator uses the git info to generate documentation. But it doesn’t initialize git. That has to be done manually.

Component Testing

Assuming that jest was installed, you can run the test suite like this:

$ npm test

Creating a Test Project

Open up another terminal window (On a Mac, in Terminal press Command-T). Go back up a directory and create a test project (I’m assuming that you have create-react-app installed):

$ cd ..
$ create-react-app my-component-test
$ cd my-component-test/
$ npm start

That should launch the test app in the browser.

Leave that running and open up another terminal window pointing to the same folder (on a Mac: Command-T).

Run the following from the new command line window:

$ sudo npm link ../my-component/

This will create a symlink for the component project in the current (test) project.

In the test project, edit this file:

src/App.js

Import the component near the top of the file by adding this line (adjust for your scope name):

import MyComponent from '@mitchallen/my-component';

Use the component inside the render return statement by adding this line above the closing div tag:

<MyComponent />

The result should look like this (adjusting for your scope name):

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

import MyComponent from '@mitchallen/my-component';

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        <MyComponent />
      </div>
    );
  }
}

export default App;

When you save the file, the browser should refresh and the page should contain these two lines near the bottom:

Package: @mitchallen/my-component
Component: MyComponent

If you got that far, everything should be working.

Updating the Original Component

You should still have a terminal window open pointing to the folder of the first project. In that project folder edit this file:

src/index.js

Add this line under the other div statements and save the file:

<div>This is a test!</div>

The file should now look like this:

/*
    Module: @mitchallen/my-component
    Author: Mitch Allen
*/

import React from 'react';
// import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  render() {
    return (
    	<div>
      	  <div>Package: @mitchallen/my-component</div>
      	  <div>Component: MyComponent</div>
          <div>This is a test!</div>
      	</div>
    );
  }
}

// MyComponent.propTypes = {
//   // someProp: PropTypes.isRequired,
// };

export default MyComponent;

The browser for the test project won’t update, because the original component needs to be rebuilt. Do the following in the original folder:

$ npm build

The change should now be reflected in the test browser display.

Suggested Reading