在你的应用程序和项目中重复使用和共享React组件,以实现更快的、一致的UI开发。
这个简短的教程是基于Debbie O'Brien撰写的React with Bit官方教程,用于重复使用组件。它将帮助你节省开发时间,提高一致性,并更容易维护你的代码库。
它将通过实践教会你一个超级高效的方法来开发可重用的组件,并以可扩展、可管理的方式在各个项目中使用它们。我们使用这种工作流程来构建我们的整个系统,包括所有的应用程序和产品--就像乐高一样。它不仅更快,而且更容易维护。
一旦完成,你将有几个组件('按钮'和使用按钮的'卡片'),它们将从一个项目中'导出'并用于另一个项目。
使用 比特的最新的 "和谐 "版本,你将在你的项目中开发解耦和独立可重用的组件。Harmony "将为你提供一个简单的开发体验,以实现这种 "类似单体 "的开发,并将为你自动完成所有的配置和定义。也没有repo efactoring。
然后你将导出(推送/发布)这些组件到远程,并从另一个项目中以包(npm/yarn)或克隆的源代码的形式使用它们。但这还不是全部;你将学习如何轻松地定制和添加mdx文档、渲染的例子、隔离测试等等。
例子 - 完整的React电子商务应用作为可重用的组件
这种方法非常有效,以后可以应用于任何项目,无论是组件库还是React中的真实世界应用。因此,让我们跳进去,开始动手操作,逐一涵盖以下步骤。
- 安装比特
- 启动一个工作区
- 创建组件
- 版本和导出(推送/发布)组件
- 以包的形式安装组件|导入(克隆/拉)组件
- 奖励:将组件组合起来
让我们开始吧!
1.安装比特
要使用Bit,我们首先需要安装BVM,Bit的版本管理器。
npm i -g @teambit/bvm
然后我们可以用它来安装Bit
bvm install
你可以通过运行bvm version命令检查Bit是否已经安装。如果你遇到任何问题,请查看 "使用BVM",因为你可能需要配置PATH全局变量。
2.2.初始化一个工作区
Bit的工作区是神奇发生的地方。它是你在Bit中开发和组成组件的地方。一个Bit工作区将任何项目变成一个多组件项目,同时使开发在各方面都很简单。
让我们使用Bit的最新 "和谐 "版本来初始化一个新的Bit工作区。最好是在一个空的目录下用Git进行版本控制来初始化一个工作区。前往该目录,然后运行。
bit init — harmony
该命令将创建一个workspace.jsonc文件,一个.bitmap文件(自动生成并映射工作空间中的组件),以及一个.bit目录,使用git时该目录通常位于.git文件夹中。
这个文件夹应该被git忽略,而workspace.jsonc文件和.bitmap文件应该受到版本控制。
安装依赖项
运行 bit install 命令来安装所有需要的依赖项。
bit install
由于我们将使用 React,我们需要安装 react 和 react-dom 作为同行依赖。对等依赖提供了主机应用程序所要提供的细节。
bit install react — type peer & bit install react-dom — type peer

配置工作区
workspace.jsonc文件是我们为工作区配置一切的方式。你可以改变名称和图标,以使工作区个性化。
默认范围被设置为 "我的范围"。你以后需要改变这一点,以便你可以将组件导出到正确的范围。
变体部分是我们如何设置我们的环境。在这里,我们需要取消对React这一行的注释,这样我们所有的组件就会使用react环境而不是默认的Node环境来设置。
# workspace.jsonc
"teambit.workspace/variants": {
在这个例子中,我们使用通配符来选择所有的组件,但你可以根据你的需要有很多变体,只选择特定的目录或省略目录。更多细节请参见变体文档。
3.创建组件
当创建一个组件时,Bit要求所有的组件文件都包含在它自己的目录中,并使用一个索引文件导出。这个目录中包含的文件应该包括组件的代码以及测试、文档、组合和样式(如果需要)。
为了使之更容易,Bit知道如何为你生成这些文件,所以你所要做的就是为你的组件选择名称和命名空间。
在ui命名空间创建一个名为button的组件。
bit create react-component ui/button
我们现在有一个按钮目录,里面有各种文件。让我们快速浏览一下创建的内容。

组件文件
button.tsx文件包含了按钮的代码。它只是一个带有文本的
注意道具中的注释--这些注释很重要,因为它们会在工作区UI的属性标签下显示出来,并且会让别人更容易理解你的组件和它应该如何被消耗。
# button.tsx
import React from 'react';
export type ButtonProps = {
export function Button({ text }: ButtonProps) {
组合文件
一个组合是一个单独呈现的组件的例子,单独或在另一个组件或甚至应用程序的上下文中。
button.composition.tsx文件包含我们的组合。这个文件导入了按钮组件,使我们能够看到它的样子。我们可以在这里添加各种组合,如主按钮组合和辅助按钮组合。
# button.composition.tsx
import React from 'react';
export const BasicButton = () => <Button text="hello from Button" />;
测试文件
button.spec.tsx是我们测试我们组件的方式。我们从组合文件中导入,因为我们想测试我们的各种组合,如测试按钮是否是主按钮或某个道具已被通过。
# button.spec.tsx
import React from 'react';
it('should render with the correct text', () => {
我们的组件使用React测试库,因此我们需要安装它,以便我们的测试能够运行。
bit install @testing-library/react
文档文件
button.docs.mdx文件是我们记录我们组件的地方。我们可以修改我们组件的描述和标签,以便更好地对我们的组件进行分类,这在搜索组件的时候会用到。
因为它是一个mdx文件,我们可以导入我们的组件,然后使用实时操场功能向我们组件的消费者展示如何使用它,让他们在现场玩组件,改变一些东西,看看它的效果。
# button.docs.mdx
---
import { Button } from './button';
## React Component for rendering text
A basic div that renders some text
### Component usage
```js
### Using props to customize the text
Modify the text to see it change live:
```js live
索引文件
index.tsx文件导出该组件。在这里我们使用命名的出口来导出组件和它的道具。
# index.ts
export { Button } from './button';
4.启动开发服务器
在我们开始之前,让我们通过运行bit status命令来确保我们的组件能够工作。
bit status

为了解决发现的问题,我们可以运行bit compile命令,它将编译我们的组件并创建缺少的dist文件夹。
start命令启动我们的开发服务器,编译我们的组件并使用热模块替换来观察变化。它通过worker运行不同的工作区任务,如测试、linters和任何由组件定义的工作区任务。
bit start
探索用户界面
当我们第一次运行这个命令时,它将需要一些时间来加载,因为它正在构建整个用户界面,其中不仅包含你的一个组件,还包含许多其他有趣的东西,我们将在下面探索。
图库概述
图库页面包含了我们所有组件的图库。在我们的例子中,我们只有一个。我们还可以看到我们组件的预览。

概览标签
点击组件将在概览标签上打开它,该标签是由我们的文档文件组成的。由于我们的文档包括一个实时操场,你可以修改文本并看到它的实时变化。这只是一个简单的例子,因此不是很令人兴奋,但对于更复杂的组件来说,你可以现场改变各种道具,看到组件的样子,这非常有用。

概览标签还包括你的组件的组成和属性。这些属性来自你的组件道具中的注释。

组合选项卡
如果你有各种不同的组合,你会在右边看到一个列表,你可以点击你想看的任何一个。你还会注意到在组件上方有一个图标,它允许你以全屏模式打开该组件,这样你就可以在工作区的用户界面之外看到该组件。

测试标签
测试标签显示我们的测试是通过还是失败。由于我们正在运行本地开发服务器,如果我们修改我们的测试并使其失败,这将自动变为红色,并显示你的测试已经失败。这意味着你不需要在终端运行任何测试命令来查看你的测试是否通过或失败,因为你可以在用户界面上直接看到它们。

这里需要注意的是,如果你的测试失败了,你试图导出你的组件,那么你会在终端看到一个信息,你将不能导出你的组件,直到测试通过。这鼓励了开发人员编写测试,因此鼓励了最佳实践。
依赖关系标签
依赖关系标签显示你的组件的依赖关系。由于我们的组件不依赖任何其他组件,所以这里没有什么可显示的,但是一旦我们开始从其他组件中组合组件,这个图表就会变得非常有用。

代码图标
在用户界面的右边,你还会看到一些图标。代码括号显示我们的组件代码。当组件被导出时,这将是非常有用的,因为代码可以很容易地被检查,而不需要打开代码编辑器。你的组件的消费者可能想在消费它之前看到代码。这对于修复错误或获得代码的反馈也很有帮助。

你还会注意到,在组件文件的列表下,它显示了组件的依赖关系。这将显示它所依赖的其他组件,以及测试库等包。
更新日志图标
由于我们还没有导出我们的组件,这个标签将显示如何导出的说明。一旦你的组件被导出,你将在这里看到一个组件版本的列表,以及任何在组件版本化时被提交的信息。

设计组件的样式
现在是时候修改我们的组件,把它变成一个真正的按钮。首先,我们可以把
由于我们想显示我们的按钮的主要和次要的变化,我们将使用HTML数据属性,它允许我们存储HTML元素的信息。我们还需要为我们的按钮元素添加data-attribute,这样我们就可以用它来为按钮设置主要和次要的变化。
# button.module.scss
.button {
&[data-variation='primary'] {
&:hover {
&[data-variation='secondary'] {
&:hover {
要在我们的按钮上使用我们的样式,我们需要导入文件,然后我们可以通过引用style.button作为className来使用它。
导入样式
# button.tsx
import styles from './button.module.scss';
你可能会注意到vscode中的一个警告,说它找不到这个文件的css模块或其类型声明。请随意忽略这个警告。
设置变体
然后,我们可以设置一个变体的道具,其可选值为primary或secondary。当我们传递我们的道具时,我们可以给它一个默认值primary,这意味着如果消费者没有为按钮添加一个变体,它将默认为primary变体。然后,我们添加我们的className,从我们刚刚导入的样式中传入我们的按钮类。为了让它工作,我们需要添加我们的数据变量,把我们创建的变量道具的值传给它。
我们还应该修改文本道具,使其更加明确,这样如果我们有另一个叫做文本的道具,我们就不会有任何问题了。让我们把它改成'buttonText'。
# button.tsx
import React from 'react';
export type ButtonProps = {
export function Button({ buttonText, variation = 'primary' }: ButtonProps) {
由于我们已经运行了开发服务器,我们可以在localhost:3000上检查我们的组件看起来如何。

创建组合体
我们现在可以为我们的二级按钮创建另一个组合。首先,让我们把BasicButton重命名为PrimaryButton,因为这是我们的组件将在用户界面中显示的名字。我们不需要给主按钮添加一个变化道具,因为我们已经设置了一个默认值primary。然后,我们可以复制和粘贴这个组合,并将其重命名为SecondaryButton,并将变体道具的值改为secondary。
export const PrimaryButton = () => (
export const SecondaryButton = () => (
现在在我们的本地工作区,你会看到我们有两个组合,在组合标签中,我们可以在主按钮和次按钮之间进行选择。


现在概览标签将显示我们的Button组合以及新的变体道具的类型和默认值。

为了改进我们的文档,我们可以用次要按钮的例子来更新实时代码块,使我们的消费者更容易玩弄这些道具,看到按钮的变化。
```js live

由于我们修改了我们的组合,你可能会注意到我们的测试现在失败了,因为它不能再找到BasicButton的组合。我们可以修复我们的测试,也可以测试每个变体。
#
import
import
import
it('should render with the correct text', () => {
const
const
expect(rendered).toBeTruthy();
});
it('should render with the correct text', () => {
const
const
expect(rendered).toBeTruthy();
});
4.构造组件
让我们创建一个消耗按钮组件的基本卡片组件。我们可以使用bit create命令来生成另一个组件,我们将称之为card。
bit create react-component ui/card
然后我们可以重新启动开发服务器,这样我们就可以看到我们的新组件。
bit start
目前,我们的卡片组件只是一个基本的div,所以让我们通过使用css模块添加一些样式来修改这个组件。
# card.module.scss
.card {
button {
然后,我们可以将我们的样式导入我们的卡片组件中。
#
import
然后将这些样式添加到我们的
export function Card({ text }: CardProps) {
导入我们的组件
为了在卡片组件中添加我们的按钮,我们需要首先导入它。Bit不允许使用相对导入,即使两个组件都在同一个目录下。原因是它们今天可能在同一个目录下,但明天可能不在了。这使得你可以轻松地改变你的代码目录结构,而不会弄乱你的组件导入,因为你的组件已经与工作区的目录结构解耦。要导入这个组件,我们需要找到它的包名,我们可以在组件的概览标签中看到。
一旦我们导入了它,我们就可以在我们的卡片组件中使用它,我们也可以导入按钮道具,并扩展我们的卡片道具,使其也包含在按钮道具中。
# card.tsx
import React from 'react';
export type CardProps = {
export function Card({ text, buttonText, variation }: CardProps) {
然后我们可以更新我们的组合文件以包括新的道具。
# card.composition.tsx
import React from 'react';
export const BasicCard = () => (

我们也可以用我们的按钮组件的新增道具来更新我们的文档实例。
# card.docs.tsx
```js live
现在我们可以在本地工作区的依赖标签下看到,我们的卡片组件正在消耗按钮组件。我们也可以在依赖关系中看到,我们的图现在包含了这两个组件,并显示卡片依赖于按钮组件。

当然,我们可以通过添加primary这个词或者省略primary这个词来创建我们组件的另一个组合,因为primary是默认值。
export const PrimaryCard = () => (

创建一个远程范围
为了导出组件,我们需要已经设置好一个范围。我们可以通过访问bit.dev并创建一个账户或登录(如果你已经建立了一个账户)来做到这一点。
bit login
一旦你登录了,你就可以创建一个新的范围/集合。由于我们的组件是UI组件,它们可能应该在一个叫做base-ui的范围内,所以让我们创建这个集合。

更新你的默认作用域
一旦我们创建了我们的作用域,我们将需要更新workspace.jsonc文件中的作用域名称,使之与你的作用域名称相同。范围名称是由你的组织或团队名称和集合名称组成的。
# workspace.jsonc
defaultScope: <user-name>.<scope-name>
链接你的节点模块#
由于我们已经改变了默认的范围,我们现在需要确保我们的节点模块被正确链接。我们可以用 bit link 命令来做这件事。
bit link
复制
现在在我们的节点模块中,我们可以看到我们在正确的范围内有这些组件。

我们现在需要手动更新我们的导入语句以反映改变后的作用域名称。
import { Button, ButtonProps } from ‘@debs-obrien/base-ui.ui.button’;
组件的版本管理
我们可以运行 bit status 命令来查看我们组件的状态。
bit status
我们可以看到我们缺少dist文件夹,为了使我们的组件在导出时能正常工作,我们需要这些文件夹。让我们通过运行bit compile命令来解决这个问题。
bit compile
现在,如果我们使用bit status,它将显示我们的组件是好的,这意味着我们已经准备好使用bit tag命令来创建我们的组件的第一个版本。使用--all标志,我们可以标记所有被修改过的版本,这意味着我们不必对每个版本进行单独标记。我们还可以为我们的组件版本添加一个信息。
bit tag — all — patch — message “first version”
导出组件
一旦组件被标记,并且所有的测试都正确通过,你就会有一个新版本的组件,因此可以使用比特导出命令导出组件。
bit export
一旦你的组件被导出,它们现在将在bit.dev上可用,因此可以被你团队的其他成员使用,如果你把范围设置为公共范围,则任何人都可以使用。

你现在还可以在 changelog 标签中看到你的组件现在有了它的第一个版本,有了你在标记它时设置的版本信息。

在卡片组件的代码标签中,你可以在代码文件下看到一个依赖性列表,你可以从那里点击它所依赖的组件,在我们的例子中是按钮组件。

安装该组件
我们可以使用yarn或npm将我们的组件安装到另一个应用程序中。让我们创建一个简单的React应用程序。
npx create-react-app use-card
然后我们可以使用yarn或npm install命令来安装组件,后面跟上组件的包名。要用包管理器安装组件,包管理器需要像注册表中的包一样访问你的组件,因此你需要将你的范围配置为一个范围注册表。这方面的细节可以在使用按钮下找到,然后选择安装标签,因为我们想用包管理器安装组件。

在你点击这个链接后,复制代码并将其粘贴到终端,将作用域配置为一个范围内的注册表。你只需要设置一次。完成后,你就可以从范围注册表/比特云中添加你的组件。
yarn add @debs-obrien/card.ui.card
现在在你的node_modules文件夹中,你会看到我们已经安装了这个组件,因此它可以像其他npm包一样使用。由于我们安装了依赖于按钮组件的卡片组件,你会看到按钮组件也被安装了。

如果你看一下文件,你会发现这个组件不是一个编译过的组件,这意味着sass文件仍然是一个sass文件,因此,如果我们想在我们的React应用程序中使用它,我们将需要包括它所依赖的包,在这种情况下就是sass。
yarn add sass
消耗该组件
让我们把它导入我们的应用程序。
# App.js
import logo from './logo.svg';
function App() {
export default App;
这样,我们的漂亮卡片组件就在我们的React应用程序中呈现了。

就这样了。现在是时候开始创建更多的组件并在你的许多应用程序和团队中使用它们了。
了解更多
我们如何重用和分享React组件》最初发表在《Bits and Pieces》杂志上,人们通过强调和回应这个故事来继续对话。
