Чаще всего для создания React-приложения мы используем наш любимый инструмент: create react app, next, gatsby…
Но это совсем другая история, когда дело доходит до создания библиотеки компонентов. Выбор не так прост. В этой статье мы расскажем, как создать библиотеку с помощью Vite и Typescript.
Почему Vite?
Vite — это современный фронтенд-инструментарий с отличной производительностью. Более подробную информацию вы можете получить здесь. Из коробки он поддерживает typescript и библиотечные связки. Поэтому это идеальный выбор для создания библиотеки React.
Как структурировать и организовать наш проект?
Давайте начнем создавать монорепо. Для управления зависимостями мы используем рабочие пространства yarn.
Чтобы настроить наше монорепо, нам нужно создать файл package.json в корне хранилища.
{
"name": "lib-example",
"private": true,
"workspaces": {
"packages": [
"packages/*",
"sites/*"
]
},
}
В репозитории есть две папки:
- packages, содержащая пакет библиотеки компонента
- sites, содержащая сайт для тестирования библиотеки.
Вот структура дерева.
react-library-vite-example
|- packages
| |- my-lib
|- sites
| |- my-site
|- package.json
|- yarn.lock
Пакет библиотеки
Внутри папки packages создадим новый проект Vite:
yarn create vite my-lib --template react-ts
По умолчанию создается веб-приложение React, настроенное на typescript. Теперь нам нужно настроить его на использование библиотечного режима из Vite.
Во-первых, мы должны установить плагин vite, который поможет нам генерировать определения типов для наших компонентов.
yarn add --dev vite-plugin-dts
Чтобы подключить библиотеку, нам нужно обновить файл vite.config.js.
import react from '@vitejs/plugin-react';
import path from 'node:path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
export default defineConfig({
plugins: [
react(),
dts({
insertTypesEntry: true,
}),
],
build: {
lib: {
entry: path.resolve(__dirname, 'src/lib/index.ts'),
name: 'MyLib',
formats: ['es', 'umd'],
fileName: (format) => `my-lib.${format}.js`,
},
rollupOptions: {
external: ['react', 'react-dom', 'styled-components'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'styled-components': 'styled',
},
},
},
},
});
Обратите внимание, что также важно экстернализировать все зависимости, которые вы не хотите собирать в библиотеку: react, react-dom и styled-components.
Наша конфигурация сворачивания генерирует два формата пакета: es и umd.
В качестве примера мы добавляем в нашу библиотеку следующий компонент кнопки (MyButton.tsx).
import styled from 'styled-components';
const MyButton = styled.button`
border: none;
border-radius: 0.5rem;
background-color: #186faf;
color: hsl(0deg, 0%, 98%);
padding: 0.75rem;
cursor: pointer;
&:hover {
background-color: #0a558c;
}
&:focus {
outline: none;
box-shadow: 0 0 0 2px #62b0e8;
background-color: #0a558c;
}
`;
export default MyButton;
Все публичные компоненты React экспортируются в файл src/lib/index.ts
.
export { default as MyButton } from './MyButton';
Вот обновленный package.json для нашей библиотеки:
{
"name": "my-lib",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"styled-components": "^5.3.3"
},
"devDependencies": {
"@babel/core": "^7.16.12",
"@types/node": "^17.0.12",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/styled-components": "^5.1.21",
"@vitejs/plugin-react": "^1.1.4",
"acorn-jsx": "^5.3.2",
"babel-loader": "^8.2.3",
"typescript": "^4.5.5",
"vite": "^2.7.13",
"vite-plugin-dts": "^0.9.9"
},
"license": "UNLICENSED",
"peerDependencies": {
"react": "^16.8.0 || 17.x",
"react-dom": "^16.8.0 || 17.x",
"styled-components": "^5.0.0"
},
"files": [
"dist"
],
"main": "./dist/my-lib.umd.js",
"module": "./dist/my-lib.es.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/my-lib.es.js",
"require": "./dist/my-lib.umd.js"
}
}
}
Запустите yarn build для компиляции библиотеки.
Поскольку мы собираем все зависимости в библиотеку (кроме внешних), нам нужно очистить package.json опубликованного пакета npm. Мы сделаем это, добавив скрипт prepack.
"prepack": "json -f package.json -I -e "delete this.devDependencies; delete this.dependencies"",
Я использую CLI для работы с JSON (yarn add -D json
).
Сайт для тестирования библиотеки компонентов
Начнем с создания нового проекта Vite в папке sites.
yarn create vite my-site --template react-ts
Нам нужно добавить следующую зависимость в наш файл package.json, чтобы протестировать нашу библиотеку компонентов:
"dependencies": {
"my-lib": "*",
...
},
Теперь мы можем ссылаться и использовать наш компонент кнопки.
import { MyButton } from 'my-lib';
function App() {
return (
<div className="App">
...
<MyButton onClick={...}>Click here!</MyButton>
...
</div>
);
}
export default App;
Запустите yarn install и yarn run dev, чтобы запустить сервер разработки.
Настройте storybook
Мы также хотим создать документацию для наших компонентов пользовательского интерфейса. Storybook — это фантастический проект, который поможет нам создать игровую площадку для наших компонентов React.
Выполните следующую команду для настройки Storybook:
cd /packages/my-lib && npx sb init --builder storybook-builder-vite
На момент написания статьи аддон взаимодействия не работает хорошо с Vite. Вот настроенная конфигурация (.storybook/main.js):
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/react",
core: {
builder: "storybook-builder-vite",
},
};
Наконец, мы создаем файл story для нашего компонента кнопки.
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import MyButton from './MyButton';
const meta: ComponentMeta<typeof MyButton> = {
title: 'Design System/MyButton',
component: MyButton,
};
export default meta;
export const Primary: ComponentStoryObj<typeof MyButton> = {
args: {
disabled: false,
children: 'Hello',
},
};
Запустите yarn run storybook, чтобы запустить Storybook.
Если вы хотите узнать больше о Storybook, ознакомьтесь с официальной документацией.
Что дальше?
Мы только что создали отличный проект запуска Vite. Но мы можем пойти дальше и настроить дополнительные инструменты, такие как eslint, prettier, jest…
Вы можете найти исходный код на Github.
Это было полезно для меня в моих проектах. Надеюсь, это поможет и вам.