Frontend Development 27 min read

Comprehensive Guide to Building a React Component and Utility Library with dumi2 (Setup, Development, Testing, and Deployment)

This article provides a step‑by‑step tutorial on using dumi2 to create a React component and function library, covering project initialization, component and style development, documentation generation, Jest unit testing, Ant Design integration, utility functions, test optimization, and final packaging and deployment to both a static site and npm.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Comprehensive Guide to Building a React Component and Utility Library with dumi2 (Setup, Development, Testing, and Deployment)

1. Introduction to dumi

dumi is a static site framework designed for component development, working together with father to provide a one‑stop experience for building component libraries, generating documentation, and publishing npm packages.

2. Installing dumi

2.1 Environment preparation

Ensure Node.js 14+ is installed:

$ node -v
v14.19.1

2.2 Create a project

Create an empty directory and run the official scaffolding tool:

mkdir dumi2-demo && cd dumi2-demo
npx create-dumi

Select the React Library template, then fill in the package name (e.g., dumi2-demo ) and other basic info.

2.3 Project structure

.
├── docs                # documentation pages
│   ├── index.md
│   └── guide
├── src                 # source code
│   ├── Button          # example component
│   └── index.ts        # library entry
├── .dumirc.ts          # dumi config
└── .fatherrc.ts        # father (npm) config

3. Developing basic components

3.1 Add component source

Create a simple Button component:

import React, { memo } from 'react';
import './styles/index.less';
export interface ButtonProps {
  type?: 'primary' | 'default';
  children?: React.ReactNode;
  onClick?: React.MouseEventHandler
;
}
const Button: React.FC
= ({ type = 'default', children, onClick }) => (
{children}
);
export default memo(Button);

3.2 Add LESS variables and styles

// src/variables.less
@dumi-primary: #4d90fe;

// src/Button/styles/index.less
@import '../../variables.less';
.dumi-btn { font-size: 14px; height: 32px; padding: 4px 15px; border-radius: 6px; transition: all .3s; cursor: pointer; }
.dumi-btn-default { background: #fff; color: #333; border: 1px solid #d9d9d9; &:hover { color: @dumi-primary; border-color: @dumi-primary; } }
.dumi-btn-primary { color: #fff; background: @dumi-primary; border: 1px solid @dumi-primary; }

3.3 Export component

// src/index.ts
export { default as Button } from './Button';

3.4 Add demo and documentation

Demo ( src/Button/demo/base.tsx ) shows default and primary buttons, and src/Button/index.md provides markdown documentation with API table.

4. Ant Design secondary development

Install Ant Design and wrap its Button :

npm i antd -D

// src/PrimaryButton/index.tsx
import React, { memo } from "react";
import { Button, ButtonProps } from "antd";

type IPrimaryButtonProps = Omit
;
const PrimaryButton: React.FC
= ({ children, ...rest }) => (
{children}
);
export default memo(PrimaryButton);

Export it in src/index.ts and document it similarly to the basic button.

5. Developing utility functions

5.1 Add formatTime function

// src/formatTime/index.ts
/**
  Format a timestamp.
  @param timestamp Milliseconds
  @param format   Format string, e.g., YYYY-MM-DD hh:mm:ss
*/
function formatTime(timestamp: number, format='YYYY-MM-DD hh:mm:ss'): string {
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = ('0' + (date.getMonth() + 1)).slice(-2);
  const day = ('0' + date.getDate()).slice(-2);
  const hours = ('0' + date.getHours()).slice(-2);
  const minutes = ('0' + date.getMinutes()).slice(-2);
  const seconds = ('0' + date.getSeconds()).slice(-2);
  const map: { [key: string]: string } = {
    YYYY: String(year), MM: month, DD: day, hh: hours, mm: minutes, ss: seconds,
  };
  return format.replace(/YYYY|MM|DD|hh|mm|ss/g, matched => map[matched]);
}
export default formatTime;

5.2 Demo and docs

Demo component displays current time, a fixed timestamp conversion, and an input for custom timestamps. Documentation is written in markdown with a parameter table.

6. Jest unit‑test optimization

6.1 Basic tests

Tests for Button , PrimaryButton , and formatTime verify rendering, class names, click handling, and correct formatting.

6.2 Full‑run script

"scripts": { "test:all": "jest --coverage --bail" }

6.3 Staged tests

A custom jest.staged.js script parses git diff --staged to run only tests related to changed source files, and it is hooked into lint‑staged for automatic execution on commit.

7. Packaging and deployment

7.1 Build static documentation site

npm run docs:build   # generates docs-dist

Serve locally with serve -s docs-dist or deploy via Nginx.

7.2 Build npm package

npm run build   # generates dist

Configure peerDependencies (React, React‑DOM, antd), add sideEffects: false for tree‑shaking, and use babel-plugin-import in .fatherrc.ts to auto‑import Ant Design styles.

7.3 Publish

npm login
npm publish

8. Summary

The guide walks through creating a reusable React component library and utility function set with dumi2, covering everything from initial scaffolding, component & style authoring, documentation, comprehensive Jest testing, CI‑friendly staged testing, to final packaging for both a static documentation site and an npm distribution.

TypeScriptreactcomponent libraryDocumentationjestdumi
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.