项目组织规范定义了如何组织一个前端项目, 例如项目的命名、项目的文件结构、版本号规范等等。尤其对于开源项目,规范化的项目组织就更重要了。

4.1 通用的项目组织规范

一个典型的项目组织规范如下:

  • README.md: 项目说明, 这个是最重要。你必须在这里提供关于项目的关键信息或者相关信息的入口. 一般包含下列信息:
    • 简要描述、项目主要特性
    • 运行环境/依赖、安装和构建、测试指南
    • 简单示例代码
    • 文档或文档入口, 其他版本或相关资源入口
    • 联系方式、讨论群
    • 许可、贡献/开发指南
  • CHANGELOG.md: 放置每个版本的变动内容, 通常要描述每个版本变更的内容。方便使用者确定应该使用哪个版本. 关于CHANGELOG的规范可以参考keep a changelog
  • package.json: 前端项目必须. 描述当前的版本、可用的命令、包名、依赖、环境约束、项目配置等信息.
  • .gitignore: 忽略不必要的文件,避免将自动生成的文件提交到版本库
  • .gitattributes: git配置,有一些跨平台差异的行为可能需要在这里配置一下,如换行规则
  • docs/: 项目的细化文档, 可选.
  • examples/: 项目的示例代码,可选.
  • build: 项目工具类脚本放置在这里,非必须。如果使用统一构建工具,则没有这个目录
  • dist/: 项目构建结果输出目录
  • src/: 源代码目录
  • tests/: 单元测试目录. 按照Jest规范, tests目录通常和被测试的模块在同一个父目录下, 例如:/src tests/ index.ts a.ts index.ts a.ts 复制代码
  • tests: 全局的测试目录,通常放应用的集成测试或E2E测试等用例
  • .env*: 项目中我们通常会使用环境变量来影响应用在不同运行环境下的行为. 可以通过dotEnv来从文件中读取环境变量. 通常有三个文件:基本上这些文件的变动的频率很少,团队成员应该不要随意变动,以免影响其他成员。所以通常会使用.env..local文件来覆盖上述的配置, 另外会设置版本库来忽略.local文件.

    • .env 通用的环境变量
    • .env.development 开发环境的环境变量
    • .env.production 生成环境的环境变量



对于开源项目通常还包括这些目录:

  • LICENSE: 说明项目许可
  • .github: 开源贡献规范和指南
    • CONTRIBUTING: 贡献指南, 这里一般会说明贡献的规范、以及项目的基本组织、架构等信息
    • CODE_OF_CONDUCT: 行为准则
    • COMMIT_CONVENTION: 提交信息规范,上文已经提及
    • ISSUE_TEMPLATE: Issue的模板,github可以自动识别这个模板
    • PULL_REQUEST_TEMPLATE: PR模板

任意一个优秀的开源项目都是你的老师,例如ReactVue
⬆️回到顶部

4.2 目录组织的风格

上面只是一个通用的项目组织规范,具体源代码如何组织还取决于你们使用的技术栈和团队喜好。网上有很多教程,具体可以搜索怎么组织XX项目. 总结一下项目组织主要有三种风格:

  • Rails-style: 按照文件的类型划分为不同的目录,例如components、constants、 typings、views. 这个来源于Ruby-on-Rails框架,它按照MVC架构来划分不同的目录类型,典型的目录结构如下: app models # 模型 views # 视图 controllers # 控制器 helpers # 帮助程序 assets # 静态资源 config # 配置 application.rb database.yml routes.rb # 路由控制 locales # 国际化配置 environments/ db # 数据库相关 复制代码
  • Domain-style: 按照一个功能特性或业务创建单独的目录,这个目录就近包含多种类型的文件或目录. 比如一个典型的Redux项目,所有项目的文件就近放置在同一个目录下:Users/ Home/ components/ actions.js actionTypes.js constants.js index.js model.js reducer.js selectors.js style.css index.js rootReducer.js 复制代码
  • Ducks-style: 优点类似于Domain-style,不过更彻底, 它通常将相关联的元素定义在一个文件下。Vue的单文件组件就是一个典型的例子,除此之外Vuex也是使用这种风格: 复制代码

大部分情况下, 我们都是使用混合两种方式的目录结构,例如:
src/ components/ # 🔴 项目通用的‘展示组件’ Button/ index.tsx # 组件的入口, 导出组件 Groups.tsx # 子组件 loading.svg # 静态资源 style.css # 组件样式 … index.ts # 到处所有组件 containers/ # 🔴 包含’容器组件’和’页面组件’ LoginPage/ # 页面组件, 例如登录 components/ # 页面级别展示组件,这些组件不能复用与其他页面组件。 Button.tsx # 组件未必是一个目录形式,对于一个简单组件可以是一个单文件形式. 但还是推荐使用目录,方便扩展 Panel.tsx reducer.ts # redux reduces useLogin.ts # (可选)放置’逻辑’, 按照👆分离逻辑和视图的原则,将逻辑、状态处理抽取到hook文件 types.ts # typescript 类型声明 style.css logo.png message.ts constants.ts index.tsx HomePage/ … index.tsx # 🔴应用根组件 hooks/ # 🔴可复用的hook useList.ts usePromise.ts … index.tsx # 应用入口, 在这里使用ReactDOM对跟组件进行渲染 stores.ts # redux stores contants.ts # 全局常量 复制代码
框架官方很少会去干预项目的组织方式,读者可以参考下面这些资源来建立自己项目组织规范:

⬆️回到顶部

4.3 脚手架和项目模板

在将项目结构规范确定下来后,可以创建自己的脚手架工具或者项目模板,用于快速初始化一个项目或代码模板。
相关资源:

  • yeoman - 老牌的项目脚手架工具
  • plop - 代码生成辅助CLI
  • hygen - 类似于plop
  • generact - 生成React组件, 大部分组件的文件结构差不多, 这个工具就是帮助你生成这些重复的代码
  • babel-code-generator - 利用babel来实现更高级的代码编辑和自动生成