使用 pnpm 和 Vite 的 React Monorepo 设置教程:React 项目 + UI、实用程序
昨天晚上,我在 的文档中发现了一个错误chakra-ui
,我最近一直在我的个人项目中使用它。我分叉了这个项目并试图找到错误。该项目被设置为 monorepo,它看起来非常有趣,因为我想有一天尝试设置一个 monorepo。我甚至把它写在了我的待办事项清单上,但我没有机会设置 monorepo。总之,我没有发现错误然后上床睡觉了。我醒得晚了几个小时。我应该睡觉了。当时是凌晨三点。但是我一直想着 mono repo 的结构,无法入睡。几分钟后,我起床并开始使用 pnpm 设置 mono repo。
我想要实现的是以下内容:
- 为 UI 组件和 Util 函数创建两个包,可以从单独的 React 项目中使用。
- 创建一个 React 项目并在 React 项目中使用这两个包。
- 对每个项目进行测试。
- 安装所有依赖项,运行开发服务器,并从根目录测试每个工作区。
由于实现这些内容是此 mono repo 的主要目标,因此没有考虑常见配置、package.json 和小细节。
在现实世界中,您可能需要考虑很多事情,而且这些事情也可能因各种因素而有所不同。
我将按照以下步骤撰写这篇文章:
此外,我还录制了整个过程并上传到我的 YouTube 频道。由于我创建这个频道是为了练习英语,考虑到我的英语水平,有些内容可能听起来并不自然。不过,如果您想更详细地了解整个过程,我还是建议您观看视频。这是一个纯粹的无剪辑视频,您可以看到我设置 Mono 仓库的所有步骤,例如我搜索了哪些内容、遇到了哪些问题以及如何从头开始解决这些问题。
好的,我们开始吧!
根项目
1.创建文件夹并初始化pnpm
> mkdir monorepo
> cd monorepo
> pnpm init
2. 创建pnpm-workspace.yaml
文件并设置工作区路径
packages:
- 'packages/*'
- 'website'
网站
1. 使用以下方式设置 React 项目Vite
> pnpm create vite
2. 安装软件包
> pnpm install
从根目录安装依赖项。
它将检测工作区并pnpm-lock.yaml
在根目录中创建一个。在锁定文件中,依赖项写在包名称下website
。
3. 添加脚本从根目录运行开发服务器
//...
"scripts": {
"dev": "pnpm --filter website dev"
},
//...
package.json
在根目录的文件中添加脚本。
该--filter
选项允许我们在工作区下执行脚本website
。
4.运行dev
命令,查看开发服务器是否启动成功
> pnpm run dev
打开http://localhost:5173
,您将看到初始页面。
软件包/实用程序
utils
1.在 下创建目录packages
。
> mkdir -p packages/utils
2. 创建package.json
{
"name": "@mono/utils",
"version": "0.0.1",
"main": "src/index.ts",
"scripts": {
}
}
该包已重命名@mono/utils
并设置了主文件路径。
3. 设置 TypeScript 环境
> pnpm install -D typescript --filter utils
> pnpm exec tsc --init
4. 在文件中创建函数
不要忘记从中导出该函数index.ts
。
5.设置vitest
并编写测试代码
> pnpm install -D vitest --filter utils
[packages/utils/src/calc.test.ts]
import { test, expect } from 'vitest';
import { add } from './calc';
test('add(10, 20) should return 30', () => {
expect(add(10, 20)).toBe(30);
});
6.在文件中添加测试脚本package.json
。
[packages/utils/package.json]
{
//...
"scripts": {
"test": "vitest run"
},
//...
}
[package.json]
{
//...
"scripts": {
"dev": "pnpm --filter website dev",
"test:all": "pnpm -r test"
},
//...
}
该-r
选项将为每个工作区执行测试命令。
7. 测试
> pnpm run test:all
包/ui
ui
1.使用设置包Vite
。
> cd packages
> pnpm create vite
由于该ui
软件包是由 创建的Vite
,因此实现 UI 组件时可能不需要的一些文件会随附其中。Vite
虽然我以前设置得很快,但您可以ui
自行设置软件包。这样更合适,因为您可以安装所需的特定依赖项并进行配置。
2.删除不必要的文件
src
目录下的所有文件- 索引.html
- 公共目录
3.安装依赖项
> pnpm install
4.创建组件
[packages/ui/src/Button.tsx]
import { ComponentProps } from "react";
const Button = (props: ComponentProps<'button'>) => {
return (
<button {...props} />
)
}
export default Button;
[packages/ui/src/index.ts]
export { default as Button } from './Button';
vitest
5. 使用和设置测试环境react-testing-library
。
> pnpm add -D --filter ui @testing-library/jest-dom vitest jsdom @testing-library/react
[packages/ui/vitest.config.ts]
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react-swc';
export default defineConfig(({ mode }) => ({
plugins: [react()],
resolve: {
conditions: mode === 'test' ? ['browser'] : [],
},
test: {
environment: 'jsdom',
setupFiles: ['./vitest-setup.js'],
},
}));
[packages/ui/vitest-setup.js]
import '@testing-library/jest-dom/vitest';
[packages/ui/tsconfig.json]
{
//...
"types": ["@testing-library/jest-dom"],
//...
}
import '@testing-library/jest-dom/vitest';
来自 vitest-setup.js 使您能够使用 jest-dom 函数,例如toBeInDocument
with vitest
。
此外,要查看正确的类型,您应该在字段中添加 jest-dom 类型types
。
6.编写测试代码
[src/packages/ui/Button.test.tsx]
import { test, expect} from 'vitest';
import { render, screen} from '@testing-library/react'
import Button from './Button';
test('Button shuold be rendered', () => {
render(<Button>Hello</Button>);
expect(screen.getByText(/Hello/)).toBeInTheDocument();
});
7.添加测试脚本
[src/packages/ui/package.json]
{
"name": "@mono/ui",
"main": "src/index.ts",
//...
"scripts": {
"test": "vitest run"
},
//...
}
该包已重命名@mono/ui
并设置了主文件路径。
8. 运行测试:全部
使用网站上的包
1.在package.json中添加依赖项
[网站/package.json]
{
//...
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@mono/ui": "workspace:*",
"@mono/utils": "workspace:*"
},
//...
}
2.安装依赖项
pnpm install
3.编写代码
[网站/src/App.tsx]
import { ChangeEvent, useState } from 'react'
import { Button } from '@mono/ui';
import { add } from '@mono/utils';
function App() {
const [nums, setNums] = useState({
a: '',
b: '',
})
const handleNumChange = (key: keyof typeof nums) => (e: ChangeEvent<HTMLInputElement>) => {
setNums(prevNums => ({
...prevNums,
[key]: e.target.value,
}));
};
return (
<div>
<input type='text' value={nums.a} onChange={handleNumChange('a')} />
<input type='text' value={nums.b} onChange={handleNumChange('b')} />
<Button onClick={() => {
alert(add(Number(nums.a), Number(nums.b)));
}}>Add</Button>
</div>
)
}
export default App
4. 结果
包起来
探索一些 mono repos,您将了解如何设置您的项目。husky,tsconfig 文件的常见设置等,您可以设置很多东西,还需要考虑版本控制,依赖关系等。
我希望您发现它有用并且编码愉快!
鏂囩珷鏉ユ簮锛�https://dev.to/lico/react-monorepo-setup-tutorial-with-pnpm-and-vite-react-project-ui-utils-5705