Features Tutorials

IntelliJ IDEA 中的工作区

亡羊补牢,犹未为晚! 如果要用一句谚语来形容一下本文要介绍的新功能 – IntelliJ IDEA 中对工作区的支持 – 这句恐怕再贴切不过了。

简介

简单来说,工作区是一个元项目,可让您同时管理多个项目。 无论是协调复杂的开发环境,还是同时处理几个不相关的项目,此功能都非常实用。

急性子须知:下文会涉及一些理论和历史,如果您迫不及待想在 IDE 中使用工作区,请直接跳到如何使用工作区一节立即体验! 此外,您还可以收看这期在线讲座以获取更多详细信息。 请注意,这项功能目前处于预览阶段,因此您可能会遇到一些 Bug 和限制。 

自 2011 年以来,我们的问题跟踪器中就一直有关于工作区支持的工单。 不过,随着 2010 年代中期微服务和单仓库的兴起,工作区似乎失去了开发的必要。 单仓库模型与 IntelliJ IDEA 侧重的“一个项目 – 多个模块”方式完全契合。 然而,用户对工作区的需求依旧在持续增长,这一点可以从 YouTrack 上不断增加的赞和支持性评论中得到证实。 接下来,我们将探究一下为什么时至今日用户仍然需要工作区。

为什么单仓库并没有取代工作区方式 

相比其他代码安排(即多仓库)方式,单仓库确实有诸多优势,例如:

  • 改善协作。 所有开发者都能即时查看项目其他部分的进展情况。 只要代码一提交,所有更改都会一目了然。 如果要实现的服务需要与其他团队开发的服务交互,开发者可以查看对方的代码,深入了解其运作方式。
  • 简化依赖项管理。 在大多数情况下,单仓库中的所有项目均使用相同的软件包管理和构建工具,便于跟踪依赖项和版本。 而且,单仓库中的所有应用程序组件通常一起发布,这就规避了项目间依赖项出现问题的风险。 
  • 跨项目重构。 由于能够访问整个代码库,IDE 可以为代码引用编制索引,从而能够检测到更改并轻松进行正确的重构。
  • 提升代码的可发现性。 新加入团队的成员可以轻松浏览整个代码库,理解不同项目和组件间的依赖关系。

如果您签出一个单仓码库并用 IntelliJ IDEA 打开,会发现单仓库的结构完美契合“项目-模块”范式。 根文件夹被视为一个“项目”,所有子文件夹则变为“模块”。 因此,从这个角度来看,该模型似乎运行良好,工作区功能的实现可以往后推迟。

不过,单仓库也存在一些不足:

  • 单仓库的规模会迅速增长。 加载庞大的代码库并收集代码的元数据可能需要耗费大量时间。 单仓库内所有项目的大量提交可能导致分支、合并和变基操作比预期耗时更长。 
  • 可能难以限制对子文件夹的访问。 例如,在 Git 中,您可以通过使用子模块或提供商特定功能(如 GitHub 的 Codeowners)来实现这一点。
  • 如果单仓库中的不同项目具有不同的发布周期,CI/CD 集成可能会面临挑战。

除了使用单仓码库所带来的纯技术难题之外,我们可以再加上行为方面的考量。 一般来说,开发者不会处理整个单仓库中的代码。 他们往往专注于一项独立的服务或者少数几项服务。 

因此,尽管使用单仓库有许多优势,但由于以下原因,它的使用已经开始减少:

  • 性能问题:当代码库规模扩大后,克隆、拉取和合并代码变得愈发困难。
  • 自主性受限:与多仓库方式相比,在单仓库中,独立于系统其他部分开发和发布某个所选项目更加困难。 此外,访问控制仍是个难题。
  • 边界不明:项目被视为一个整体,因此代码和抽象可能会“泄漏”到其他项目中,产生紧密耦合。 另一个后果是“master 分支受损”。 如果单仓库中的某个项目出问题,整个代码库都会被视为损坏。
  • 开发者注意力分散:开发者通常只专注于一个小项目,但如果使用单仓库,他们必须处理包含多个项目的代码库。

由于上述问题的存在,问题 IDEA-65293 的投票量不断增加,这使得我们意识到必须在 IDE 中引入工作区这项新功能。 

调查显示,微服务开发者在开发时倾向于使用多仓库,这一趋势正在增长。这也充分证实了上面的结论。

工作区能够提升开发者在处理多个项目和仓库时的体验。 此外,工作区对更喜欢使用单仓库的开发者同样有利。 可以从庞大的单仓库中签出特定项目并专注于这些项目,这是一大优势。

如果您想深入了解此主题,可以参考一些有用的文章,如 The issue with monoreposMonorepo is a bad idea,其中对相关问题进行了更详细的解释。

什么是工作区?

在 JetBrains 支持论坛的一次讨论中,有人提出了以下观点:

项目:本质上是对最终软件产品的描述。
工作区与实际项目和/或软件产品无关! 理想情况下,它是您的 IntelliJ IDEA 的桌面,仅仅用于存储您当前处理的项目。 它是开发者环境的当前视图。 它本身并不产生结果,但会影响结果的生成方式。

这是对本插件中引入的“工作区”概念的最佳解释。 您可以将工作区视为您所处理的项目的集合。 每个项目都可以使用自己的技术栈和构建工具,并能够独立运行。

工作区用户场景

在开发这款插件时,我们考虑了一种“典型”的应用程序设置,包括:

  • 一套后端服务。
  • 一个 API 网关。
  • 客户端应用程序,例如 React Web 应用或移动应用。
  • 一组在各个服务中使用的自定义库(例如,Spring Boot 启动器)。

这些组件的代码可能会集中在一个单仓库中,或者分布在多个仓库中。 开发者可能还需要创建小型的“卫星”应用程序,以便测试和调试诸如库之类的组件,而无需将这些辅助应用提交到主代码库中。

需要注意的是,这种架构设置可能会有所不同。 例如,在单体式应用程序中,后端可能会整合为一项服务,API 网关可能变成可选项。 而在另一个场景中,如果某个应用程序没有客户端接口,则重点将完全放在后端服务和 API 网关上。

基于这些,我们针对插件提出了以下主要用例及相应的工作区配置:

1. 全栈开发者

在很多情况下,我们需要同时更新前端和后端组件,而它们可能存储在不同的仓库中。 借助工作区插件,我们可以独立签出各个仓库中的项目,将它们添加到同一个工作区中,然后像操作单个项目一样处理它们的代码。

2. 微服务开发者

假设一个单仓库中有数十项微服务,但我们只需更新其中的一部分。 我们不再需要将整个仓库导入 IntelliJ IDEA。 我们可以创建一个工作区,只添加需要的服务。 不仅如此,我们还可以为不同的项目使用不同的构建工具。 例如,一个服务使用 Maven 构建,另一个使用 Gradle 构建,这都不是问题!

3. 库开发者

当我们需要一个简单的“Hello, World!”应用程序来测试解决方案时,可以使用此场景。 Spring Boot 启动器的开发就是一个很好的例子。 测试应用程序不会被提交到代码仓库中,但我们可能需要它来简化开发。 在这种情况下,除了启动器项目外,我们还可以直接在工作区中创建一个简单项目,运行该应用,调试启动器,然后将应用丢弃或在另一个工作区中重用。

当前实现

工作区是一个独立的文件夹,用于存储对其他文件夹中项目的引用。 此外,如果需要,我们也可以在工作区文件夹内创建项目。 工作区不会对项目设置产生侵入性影响。 IntelliJ IDEA 将项目设置(如代码样式、SDK 等)存储在项目特定文件夹的一个独立文件 (.idea) 中。 当我们将一个项目添加到工作区时,IntelliJ IDEA 会将其设置复制到工作区文件夹中,然后我们可以在本地更改。 这意味着同一个项目可以被添加到多个工作区中,并使用不同的设置。 下图展示了运作方式。 

由于工作区功能仍在开发中,我们将其作为一个独立的非捆绑插件推出,在根据用户反馈持续改进的过程中力求更快地发布。 我们希望这项功能最终能够整合为 IDE 的核心功能之一。

如何使用工作区

  • 为工作区文件夹命名,并将需要的所有项目添加进去。

您可以使用 IDEA 中的常用运行配置或 Maven/Gradle 命令单独运行项目。 要同时运行多个项目(例如微服务),您可能需要使用专门的 Shell 脚本或 Docker Compose 文件。 我们力求让用户体验尽可能贴近以往的使用习惯。

当前版本的局限

我们想分享一些已知的局限。 下面所列的内容并不详尽,但包含一些可能对您至关重要的问题,这些问题可能会阻碍您立即体验工作区。 

  • 我们目前不会将所含项目的运行配置复制到工作区中。 您需要在导入项目后手动创建运行配置。
  • 设置不会持续同步。 例如,如果您在项目中使用 JDK 17 并将其添加到工作区中,工作区将使用 JDK 17。 但如果我们在“主”项目设置中将 JDK 升级到更高版本,工作区将不会“看到”这一变化。
  • 不支持项目重命名。
  • 跨独立项目的依赖关系解析仍在开发中。

您可以在 YouTrack 工单 IDEA-65293 中找到完整问题列表的链接。 

其他计划

我们正在积极推进多个任务的实现,以进一步优化对工作区的支持,主要包括:

  • 项目设置同步。
  • 在 VCS 中存储并共享工作区。
  • 支持更多构建工具。
  • 使工作区成为所有 IDE 中的“明星”功能。
  • 简化同时运行多个项目的运行配置。
  • 实现跨项目的流畅调试。

期待您的反馈! 

工作区功能仍在完善中。 我们才刚刚起步,正朝着打造理想 IDE 的目标稳步迈进。 非常期待大家的反馈,这对我们极其宝贵! 欢迎大家体验全新的工作区功能,并分享您的想法。 您的反馈将帮助我们让 IntelliJ IDEA 更加出色。 您可以在插件页面上为我们评分,或者在 YouTrack 上分享您的想法并报告问题。

如果您喜欢我们的这一举措,别忘了给我们五星好评!

本博文英文原作者:

Andrey Belyaev

Andrey Belyaev

Aleksey Stukalov

Aleksey Stukalov

Today I’m leading the IntelliJ IDEA division at JetBrains, overseeing strategic initiatives and operations within the department. Before joining JetBrains, my career journey took me through various roles: starting as an ordinary developer, being a project manager, serving as a developer advocate, CTO and even as a product manager. Through the entire carrier way my passion has always been leaned towards software engineering work, so I found my zen in frameworks and tooling development. This naturally led me to become a founder of the widely-used JPA/React Buddy plugins, which boast hundreds of thousands of users worldwide. Today both tools are proud members of the JetBrains family!

image description

Discover more