菜单

项目结构与构建过程

相关源文件

本文档概述了 Zustand 仓库的结构,并解释了用于编译、测试和发布该库的构建流程。它面向希望了解代码库组织方式以及在更改 Zustand 时如何使用构建系统的贡献者。

存储库结构

Zustand 仓库遵循一种简洁的组织模式,旨在维护整洁的代码库,同时支持多种分发格式。

来源:package.json1-172 tsconfig.json1-26

源代码组织

src/ 目录中的源代码围绕着反映 Zustand 架构的核心模块进行组织

  • 核心模块:库的基本构建块
    • vanilla.ts - 核心状态管理功能
    • react.ts - vanilla store 的 React 绑定
    • shallow.ts - 相等性比较实用工具
  • 中间件系统:通过可组合的中间件增强核心功能
    • middleware.ts - 中间件中心
    • middleware/ 目录,包含单独的中间件实现
      • immer.ts
      • persist.ts
      • devtools.ts
      • subscribeWithSelector.ts
      • 以及其他

这种组织方式允许用户在仅导入库的特定部分时进行 tree-shaking。

来源:package.json50-52 tsconfig.json18-22

构建系统

Zustand 使用 Rollup 作为其构建工具,从 TypeScript 源文件创建多种分发格式。构建系统配置为同时生成 CommonJS (CJS) 和 ECMAScript Modules (ESM) 输出,以及 TypeScript 声明文件。

来源:package.json54-65

构建脚本

package.json 定义了几个处理构建流程不同方面的构建脚本

  • build - 主构建脚本,运行所有其他构建脚本
  • build:base - 构建基本功能
  • build:vanilla - 构建 vanilla store 实现
  • build:react - 构建 React 绑定
  • build:middleware - 构建中间件系统
  • build:middleware:immer - 专门构建 Immer 中间件
  • build:shallow - 构建浅比较实用工具
  • build:vanilla:shallow - 构建带浅比较的 vanilla store
  • build:react:shallow - 构建带浅比较的 React 绑定
  • build:traditional - 构建传统 API

在主构建步骤之后,运行后处理脚本以

  1. 修补 TypeScript 声明文件
  2. 将文件复制到分发目录
  3. 处理 ESM TypeScript 声明
  4. 创建 TypeScript 向后兼容文件

这个多步构建过程确保所有分发格式都能正确生成,并且 TypeScript 用户能够获得最佳的类型支持。

来源:package.json54-78

Rollup 配置

Rollup 配置用于处理

  1. 通过 @rollup/plugin-typescript 进行 TypeScript 编译
  2. 通过 @rollup/plugin-node-resolve 进行模块解析
  3. 通过 @rollup/plugin-alias 进行路径别名
  4. 通过 rollup-plugin-esbuild 进行代码转换
  5. 通过 @rollup/plugin-replace 进行环境变量替换

该配置生成多个入口点,从而实现 tree-shaking,以在消费应用程序中实现最小的捆绑包大小。

来源:package.json112-116

包导出配置

Zustand 提供了精心配置的导出,以支持 CommonJS 和 ESM 环境,以及 TypeScript 用户。此配置在 package.json 文件中定义。

package.json 中的 exports 字段配置了这种双格式支持

exports: {
  "./package.json": "./package.json",
  ".": {
    "import": {
      "types": "./esm/index.d.mts",
      "default": "./esm/index.mjs"
    },
    "default": {
      "types": "./index.d.ts",
      "default": "./index.js"
    }
  },
  "./*": {
    "import": {
      "types": "./esm/*.d.mts",
      "default": "./esm/*.mjs"
    },
    "default": {
      "types": "./*.d.ts",
      "default": "./*.js"
    }
  }
}

此配置确保打包器和模块系统能够为其环境选择合适的格式。

来源:package.json27-48

TypeScript 配置

Zustand 使用现代 TypeScript 功能来提供出色的类型安全和开发者体验。TypeScript 配置旨在与双格式输出 (CJS/ESM) 配合使用。

关键 TypeScript 设置包括

  • 目标:ESNext,用于现代 JavaScript 功能
  • 启用严格类型检查
  • JSX 支持,用于 React
  • ESModule 互操作性,用于兼容性
  • 生成声明文件

该项目为 TypeScript 版本提供了特殊处理,兼容 TypeScript 4.5 及以上版本,这在 package.json 的 typesVersions 字段中指定。

来源:tsconfig.json1-26 package.json9-26

类型声明生成

构建过程为 CJS 和 ESM 格式生成类型声明。ESM 声明使用 .mts 扩展名来指示 ESM 兼容性。

使用特殊的构建后脚本来

  1. 更新声明文件中的导入路径
  2. 为旧版 TypeScript 添加兼容性文件
  3. 将 CJS 声明文件转换为 ESM 格式

来源:package.json75-78

持续集成和部署

Zustand 使用 GitHub Actions 进行持续集成和部署。CI/CD 管道确保库在不同环境下的正确运行。

来源:.github/workflows/test-multiple-versions.yml1-35 .github/workflows/test-old-typescript.yml1-56 .github/workflows/test-multiple-builds.yml1-52 .github/workflows/publish.yml1-24

跨环境测试

CI 管道测试 Zustand 在以下环境下的运行情况

  1. 多个 React 版本:从 React 18.0.0 到最新的 19.x canary 版本
  2. 多个 TypeScript 版本:从 TypeScript 4.5 到最新版本
  3. 不同的构建输出:开发和生产模式下的 CJS 和 ESM 构建

这种全面的测试确保了与不同环境和依赖版本的最大兼容性。

来源:.github/workflows/test-multiple-versions.yml10-34 .github/workflows/test-old-typescript.yml10-55 .github/workflows/test-multiple-builds.yml10-51

发布流程

发布流程通过 GitHub Actions 自动化

  1. 创建并发布新的 GitHub Release
  2. 发布工作流自动触发
  3. 库将被构建并以适当的版本发布到 npm

发布的包仅包含生产使用所需的文件,排除仅开发使用的文件。

来源:.github/workflows/publish.yml1-24 package.json76-77

开发工作流

要进行 Zustand 的开发,请遵循以下步骤

  1. 设置:使用 pnpm install 安装依赖项
  2. 开发:
    • src/ 目录中修改源文件
    • tests/ 目录中编写测试
  3. 测试:
    • 运行 pnpm test:types 来检查 TypeScript 类型
    • 运行 pnpm test:spec 来运行单元测试
    • 运行 pnpm test:lint 进行代码风格检查
    • 运行 pnpm test:format 来检查代码格式
  4. 构建:
    • 运行 pnpm build 来创建完整的构建
    • 检查 dist/ 目录以获取输出文件

该项目使用了一组标准的 npm 脚本进行开发

脚本目的
test运行所有测试
test:types验证 TypeScript 类型
test:spec使用 Vitest 运行单元测试
test:lint使用 ESLint 检查代码
test:format使用 Prettier 检查代码格式
fix修复代码风格和格式问题
build创建完整的构建

来源: package.json54-77 package.json67-74

结论

Zustand 的项目结构和构建过程旨在支持多种分发格式,确保类型安全,并保持跨不同环境的兼容性。使用 Rollup 等现代构建工具以及通过 CI/CD 流水线进行的全面测试,有助于维护库的质量和可靠性。

理解这种结构对于想要更改代码库、添加新功能或修复 bug 的贡献者至关重要。