精简React的单体项目

458 阅读9分钟

Nx是一个具有一流的React支持的monorepos的构建框架。它有助于加速在许多规模和范围的项目中采用成熟的开发实践。Nx为React项目提供额外的工具,以帮助以更快的速度扩展和开发功能。

本指南介绍了Nx提供的一些工具,Nx工作区的创建和结构,并附有一个例子。

什么是单片机

单库是你所有源代码的一个集合,它跨越了多个应用程序、库和语言。单库中的所有东西都不是同时部署的,而是都位于一个中心库中。许多公司为不同的组织和项目使用monorepos。有些公司甚至用一个单一的单库来存放整个公司的项目的所有源代码。

以下是单库的一些好处。

  • 共享代码- 促进验证代码、UI组件和类型在整个代码库中的重复使用,包括后台和前台之间的代码。
  • 原子修改- 对服务器API进行修改,并在同一提交中修改使用该API的客户端。不再需要在不同的存储库中协调提交。
  • 开发人员的流动性- 为使用不同工具和技术编写的应用程序的构建和测试提供一致性。开发人员可以自信地对其他团队的应用程序做出贡献,并验证他们的修改是安全的。
  • 一套依赖性- 为你所有的应用程序使用单一版本的第三方依赖性。不太常用的应用程序不会因为一个3年前的框架库或一个旧版本的构建工具而被落下。

单一版本也有一些常见的误解。

  • 严格地把你的代码放在一起,只是把所有的代码放在同一个仓库里。
  • 在每个PR或提交的所有应用程序上运行所有的构建、测试和质量检查。
  • 在每次提交时将每个应用程序部署到主分支。
  • 在各应用程序中设置多个脚本来处理常见的任务。

仅仅因为你把所有的代码都放在一个单版本中,这并不意味着你已经为每一次提交在单版本上运行了所有的测试和检查。这不能很好地扩展,并导致你的开发和持续集成(CI)和持续部署(CD)管道的瓶颈。Nx提供集成工具,通过代码分析、受影响的命令和计算缓存,智能地确定需要运行的内容。

受影响的命令

Nx使用代码分析来建立工作区中所有项目的依赖图。然后根据你在 Git 分支和主分支之间的改动,利用依赖关系图来确定哪些项目受到影响。Nx的 "受影响的命令"使用这种代码分析来执行基于更改内容的最小任务集。让我们以两个依赖一个库的应用程序为例来看看。

要看哪些应用程序受到影响,使用**nx affected:apps 命令**。Nx分析变化的性质,确定哪些项目,包括应用程序和库,受到影响。在上面的例子中,改变app1不会导致app2受到影响,所以你不需要为app2运行所有的预合并步骤。另外,改变两个应用程序所依赖的库或包也会影响两个应用程序。

计算缓存

Nx很聪明,它还知道你运行特定命令的背景,文件的当前哈希值,以及其他环境信息。

上面的图片显示了一个收集信息的例子,以建立一个独特的哈希值,用于识别计算。有了这些信息,Nx就可以缓存和存储这些计算,如果看起来相同的计算被再次运行,就可以重新播放它们。

这并不是通过重建源代码来完成的。只有从一个给定的命令中产生的工件被存储起来,并在可能的情况下进行重放。如果Nx没有找到这个计算,Nx就会运行这个任务,在它完成后,它就会把输出和终端输出的结果存储在本地(如果配置了远程)。所有这些都是透明地发生的,所以你不必担心。

使用React预设创建一个Nx工作区

现在你知道了Nx是如何工作的,让我们通过建立一个列出星球大战人物的小程序来试试。

首先,用React应用程序创建Nx工作区,使用react 预设。

npx create-nx-workspace sw-org --preset react --appName myapp

运行这个命令后,你会被要求选择一个样式表格式。你可以为这个演示选择默认的。如果你愿意,你也可以选择将你的工作空间连接到Nx Cloud

在你做出选择后,这个命令会做以下工作。

还有其他可用的预设,例如next ,用于Next.js项目,以及 react-express用于预设了React和Express的工作区。

每个Nx工作区都有一个类似于此的文件结构。

myorg/
├── apps/
├── libs/
├── tools/
├── workspace.json
├── nx.json
├── package.json
└── tsconfig.base.json
  • /apps/包含应用程序项目。这是每个可运行的应用程序的主要入口点。
  • /libs/包含库项目。每个库都定义了它的外部API,以便库之间的界限保持清晰。
  • /tools/包含对你的代码库采取行动的脚本。
  • /workspace.json包含工作区中每个项目的配置。
  • /nx.json添加关于项目的额外信息,包括隐含的依赖关系和标签,可以用来限制项目之间相互依赖的方式。
  • /tsconfig.base.json设置了全局的TypeScript设置和别名。

要提供应用程序,请进入 sw-org目录,使用Nx CLI运行serve 命令。

nx serve

注意:如果你不想全局安装Nx,你可以使用npx nx serve 来代替。

显示初始应用页面。

生成一个特征库

在Nx工作区生成库是通过使用Nx CLI的generate 命令完成的。特征库用于向用户显示用户界面,其中可能包括路由信息,并可能使用其他库,如共享组件。

现在通过运行创建一个。

nx generate lib people

注意 Nx Console还提供了一个完整的GUI,在你的编辑器中运行Nx CLI命令,并支持本地VSCode和WebStorm。

生成一个数据访问库

一个 "数据访问 "库是为一个特征获取和存储数据的功能存在的地方。因此,任何管理报价所需的服务都被放在这个库中。在整个构建应用程序的过程中,会有跨越多个功能的数据访问库。

通过运行创建数据访问库。

nx generate lib data-access

注意你也可以在Nx工作空间内创建类似于library 生成器的你的自定义生成器。这提供了更多的灵活性,围绕你的开发过程和准则创建更多的标准。在我们的工作区生成器指南中阅读更多关于工作区生成器的信息。

更新数据访问库,从《星球大战》的API中获取角色。

打开 data-access.tsx并将其替换为以下内容。

import { useEffect, useState } from "react";

export interface IPerson {
 birth_year: string;
 eye_color: string;
 films: string[];
 gender: string;
 hair_color: string;
 height: string;
 homeworld: string;
 mass: string;
 name: string;
 skin_color: string;
 created: Date;
 edited: Date;
 species: string[];
 starships: string[];
 url: string;
 vehicles: string[];
}

export interface Response<T> {
 count: number;
 next: null | string;
 previous: null | string;
 results: T[];
}

export function usePeople(page: number) {
 const [people, setPeople] = useState<IPerson[]>([]);

 useEffect(() => {
   fetch(`https://swapi.dev/api/people/?page=${page}`).then((r) =>
   r.json().then(data => data.results)
 ).then(data => {
     setPeople(data);
   });
 }, []);

 return people;
}

现在更新人物功能,在 people.tsx以列出这些人物。

import { usePeople } from '@sw-org/data-access';
import './people.module.css';

export function People() {
 const people = usePeople(1);
  return (
   <div>
     <h1>Star Wars People</h1>

     <ul>
       {
         people.map(person => (
           <li key={person.name}>
             {person.name}
           </li>
         ))
       }
     </ul>
   </div>
 );
}

export default People;

People 组件替换App 模板

import styles from './app.module.css';

import { People } from '@sw-org/people';

export function App() {
 return (
   <div className={styles.app}>
     <People/>
   </div>
 );
}

export default App;

刷新应用程序会显示一个角色列表。

角色列表很简单。业务和数据逻辑被保存在库中。随着你的应用程序的增长,库的数量也会随之增长,但应用程序仍然相对较小,只用于集成应用程序运行的核心功能。

依赖关系图

Nx知道你的工作空间中的项目之间的依赖关系,并且可以在任何时间点上直观地生成你的依赖图。

运行nx dep-graph命令可以看到工作区的当前状态。

nx dep-graph

这将显示应用程序、E2E项目和两个库。

注意:你也可以用以下标志让依赖关系图自动刷新 --watch标志让依赖关系图自动更新。

你还可以看到哪些项目会受到某个特定变化的影响。对App.tsx做一个改变,比如删除className ,保存,并运行nx affected:dep-graph命令。

nx affected:dep-graph

这将显示myappmyapp-e2e作为受影响的项目以红色显示。

注意: myapp-e2e应用程序直接与mapp挂钩,但通过nx.json文件隐式链接。在这里阅读更多关于Nx配置的信息。

使用受影响的命令

Nx提供受影响的命令来对受影响的项目运行某些任务。例如,对 data-access库,并运行nx affected:build

nx affected:build

Nx找到因改变数据访问 库而受到影响的应用程序,并为它们中的每一个运行构建目标。这样一来,只有受影响的项目会被构建,而不是monorepo中的每个项目。同样的命令也适用于testlinte2e,以及其他。

还有一个nx affected命令,对任何定义的目标都有效。nx affected:build的别名是。

nx affected --target=build

这允许你在受影响项目的基础上运行任何目标。

使用计算缓存

除了受影响的命令外,Nx还支持 计算缓存,以避免两次执行相同的计算。这个计算缓存是可插拔的,并且可以分布。以 **myapp为例,运行myapp 的构建两次。

nx build myapp

当第二次运行相同的命令而不做任何改动时,你会立即得到之前计算的缓存结果。计算缓存是在本地完成的,但也可以分布和扩展到你的团队和组织的其他成员。

Nx云就是这样一个分布你的计算缓存的选择。它包括每月节省5小时的免费层,企业选项,并且对开源项目是免费的。

总结

Nx提供了现代化的工具,包括代码分析、代码生成、代码分析、受影响的命令和计算缓存,以使用monorepo扩展你的应用开发。

我们讲了什么?

  • 单元组以及为什么你应该使用单元组
  • Nx工作区的结构和标准化
  • 使用代码分析、受影响的命令、依赖性可视化和计算缓存的更智能的工具。

通过以下资源了解更多。