IntelliJ IDEA 2025.3 Help

教程:Bazel 入门

Bazel 是 Google 开发的开源构建和测试工具。 它旨在管理具有复杂依赖关系的大型代码库,支持多种语言和平台。 Bazel 自动化了编译代码、链接依赖项、运行测试和部署工件的过程。

本教程将帮助您在 IntelliJ IDEA 中开始使用 Bazel。 完成本教程后,您将:

  • 创建新的 Bazel 项目

  • 了解 Bazel 项目结构和术语

  • 重命名存储库

  • 向项目添加 Java 源代码

  • 构建并运行项目

  • 添加包含 Kotlin 源代码的包,并从 Java 代码中调用它

  • 获取 JAR 构建产物

  • 了解如何使用项目视图

前提

对于本教程,您只需要 Bazel 插件。

安装 Bazel 插件

  1. Ctrl+Alt+S 打开设置,然后选择 插件

  2. 打开 Marketplace 选项卡,找到 Bazel 插件,然后点击 安装

  3. 重启 IDE 以激活插件。

创建项目

  1. 启动 IntelliJ IDEA。

    如果打开欢迎屏幕,请单击 新建项目

    否则,请在主菜单中转到 文件 | 新建 项目

  2. 为项目命名,并选择 Bazel 作为构建系统。

    新建项目对话框
  3. (可选)如果您希望对该项目进行版本控制,或稍后将其发布到 GitHub,请选中 创建 Git 仓库

  4. 点击 创建(C)

IntelliJ IDEA 会生成项目文件。 之后,它会与 Bazel 同步,这可能需要一段时间。

项目结构和术语

如果您是 Bazel 新手,以下是对该项目的快速导览。 其中介绍了定义 Bazel 项目构建方式的主要概念和文件。 在本教程的后续部分中,我们将引用这些概念和文件。

如果您已经熟悉 Bazel,您可以跳过本节。

主存储库

我们正在查看的项目称为 主存储库。 在 Bazel 术语中, 存储库是用于构建软件的文件集合。

由于我们正在构建 Java 应用程序,因此还需要其他存储库,例如编译器可执行文件和代码依赖项。

工作区

工作区是用于指代构建主存储库所需的全部存储库集合的术语。

模块

除了是一个存储库之外,我们的项目还是一个 模块。 模块是在 Bazel 中进行依赖管理的单位。 模块在 MODULE.BAZEL 文件中定义。

在我们的项目中, MODULE.BAZEL 文件以模块声明开头,用于设置该模块的名称和版本:

module( name = "null", version = "0.1.0", )

它将工作区声明为用于 bzlmod (Bazel 的内置依赖管理系统)的 Bazel 模块。 如果某个存储库随后发布到注册表,此声明会为其赋予唯一标识,大致相当于 Maven 的构件坐标。 这样,其他 Bazel 项目就可以将其用作依赖项。

然后, MODULE.BAZEL 指定用于处理 Java 语言以及外部 JVM 依赖项的依赖项:

bazel_dep(name = "rules_java", version = "8.10.0") bazel_dep(name = "rules_jvm_external", version = "6.7")

这两个依赖项都会导入包含所需文件的存储库。 您可以通过引用模块来添加依赖项。 引用某个模块可能会导入单个存储库或一组存储库。

文件的其余部分会加载 Maven 扩展,指向来自 Maven Central 的库,并在工作区中以名称 @maven 公开生成的存储库:

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") maven.install( name = "maven", artifacts = [ "junit:junit:4.13.2", ], repositories = [ "https://repo1.maven.org/maven2", ], ) use_repo(maven, "maven")

您可以在 排除的目录 视图中找到生成的存储库,包括传递依赖。

是 Bazel 构建过程的单位。 包通过其目录中的 BUILD.BAZEL 文件来标识。

在我们的项目中,有两个 Bazel 包:一个用于源代码,另一个用于测试:

项目工具窗口中的两个 BUILD.BAZEL 文件

包包含所有子目录,但具有自己 BUILD.BAZEL 文件的子目录除外。

源代码包的 BUILD.BAZEL 包含以下内容:

load("@rules_java//java:defs.bzl", "java_binary")

load() 语句会从 defs.bzl 文件中导入符号(例如 java_binary)。 defs.bzl 来自我们通过 bazel_dep() MODULE.BAZEL 文件中导入的 @rules_java 外部存储库。

导入符号后,我们便可以在此 BUILD.BAZEL 文件中使用它们。

package(default_visibility = ["//visibility:public"])

package 内置函数用于设置包的元数据(目前仅设置可见性)。 在此情况下,包的可见性为 public ,因为测试需要引用该包。

java_binary( name = "Main", main_class = "org.example.Main", srcs = glob(["**/*.java"]), )

java_binary 规则调用定义了名为 Main 的构建目标。 它会根据包中的 Java 源文件构建一个 JAR 文件。 main_class 属性指定应用程序的 main 类。 srcs 属性指定要包含到 JAR 中的源文件。

用于测试包的 BUILD.BAZEL 与之类似,但它额外添加了两个依赖项:一个用于 JUnit,另一个用于被测包。

java_test( name = "tests", srcs = glob(["**/*.java"]), test_class = "org.example.MainTest", deps = [ "//src/main/org/example:Main", "@maven//:junit_junit", # JUnit 4 dependency from Maven ], )

在依赖坐标中, @maven 是存储库名称, junit_junit 是构件名称。

查看已导入的存储库

每个导入的模块对应项目中的一个或多个存储库。 您可以在 bazel-{project name}/external 文件夹中查看项目使用的存储库:

项目工具窗口中的外部依赖项

如果查看 BUILD.BAZEL 文件,您会发现其中的依赖项比 外部 文件夹中的存储库数量更少。 这是因为每个导入的模块可能还依赖于更多模块。 Bazel 会识别此类传递依赖并为您导入。

运行 Bazel 目标

在对项目进行更改之前,先确认它确实可以构建并运行。 有多种方式可以实现这一点。 在本教程中,我们将使用 Bazel 工具窗口。

  1. 在右侧边栏,单击 Bazel 图标。 您也可以从主菜单中选择 视图 | 工具窗口 | Bazel

    右侧边栏上的 Bazel 工具窗口图标

    这将打开 Bazel 工具窗口,其中列出了在 BUILD.BAZEL 文件中定义的目标。

  2. Bazel 工具窗口中,右键单击 Main 目标并选择 运行

    在 Bazel 工具窗口中右键单击 Main 目标时会出现菜单

或者,如果编辑器中当前显示有 main 方法,您可以使用装订区域图标运行它。

单击主类旁的装订区域图标时会出现菜单

重命名存储库并同步更改

正如我们在 概览中所见, install() 调用会为每个已解析的构件生成一个 Bazel 外部存储库:

maven.install( name = "maven", artifacts = [ "junit:junit:4.13.2", ], repositories = [ "https://repo1.maven.org/maven2", ], )

由于它将 名称 设为 maven ,我们将生成的存储库引用为 @maven ,例如 @maven//:junit_junit

假设我们希望用另一个名称引用它,例如 第三方。 为此,让我们更改生成的存储库名称。

重命名生成的存储库

  1. MODULE.BAZEL 中,更改 install()use_repo() 调用的 名称 属性。

    maven.install( # before # name = "maven", name = "third-party", # after artifacts = [ "junit:junit:4.13.2", ], repositories = [ "https://repo1.maven.org/maven2", ], ) # before # use_repo(maven, "maven") use_repo(maven, "third-party") # after
  2. 在测试包的 BUILD.BAZEL 中,更改标签。 这是唯一引用该存储库名称的包。 否则,还必须更改所有其他引用。

    java_test( name = "tests", srcs = glob(["**/*.java"]), test_class = "org.example.MainTest", deps = [ "//src/main/org/example:Main", # before # "@maven//:junit_junit", "@third-party//:junit_junit", # after ], )

更改项目配置后,您需要重新同步项目,以便 Bazel 获取这些更改。

重新同步项目

  • Bazel 工具窗口的工具栏上,单击 重新同步项目 按钮。

    Bazel 工具窗口工具栏上的 '重新同步项目' 按钮

为依赖项添加源代码

如果我们转到用于测试包的 assertEquals() 方法的定义 Ctrl+B ,IntelliJ IDEA 会将我们带到该类文件的反编译版本。

JUnit 类的反编译版本位于

这是因为导入的存储库仅包含已编译的类,而不包含其源代码。 让我们通过指示 Bazel 在生成存储库时同时包含源代码来解决此问题。

添加源代码

  1. 打开 MODULE.BAZEL 文件。

  2. fetch_sources 参数添加到 install() 调用中,如下所示:

    maven.install( name = "third-party", artifacts = [ "junit:junit:4.13.2", ], repositories = [ "https://repo1.maven.org/maven2", ], fetch_sources = True )

要使更改生效,我们需要再次重新同步项目。

重新同步项目

  • Bazel 工具窗口的工具栏上,单击 重新同步项目 按钮。

    Bazel 工具窗口工具栏上的 '重新同步项目' 按钮

让我们再次尝试导航到 assertEquals() 定义 Ctrl+B

编辑器选项卡,打开的 Assert.java 文件(未反编译)

现在这些是 JUnit 类的实际源代码,而不是反编译版本。

添加 Kotlin

作为下一步,让我们添加一个包含使用 Kotlin 的库的单独包。

添加 Kotlin 依赖项

添加构建规则

  • MODULE.BAZEL 文件中,将用于导入 Kotlin 规则(rules_kotlin 2.1.8 )的语句粘贴到文件顶部:

    module( name = "null", version = "0.1.0", ) bazel_dep(name = "rules_java", version = "8.10.0") bazel_dep(name = "rules_jvm_external", version = "6.7") bazel_dep(name = "rules_kotlin", version = "2.1.8") maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") maven.install( name = "third-party", artifacts = [ "junit:junit:4.13.2", ], repositories = [ "https://repo1.maven.org/maven2", ], fetch_sources = True ) use_repo(maven, "third-party")

添加规则后,我们可以继续添加一个包含 Kotlin 源代码的包来使用这些规则。

添加包含 Kotlin 源代码的包

  1. 切换到 项目 工具窗口。 选中根文件夹后,按 Alt+Insert ,或右键单击它并选择 新建 | Bazel 包

  2. 为该包命名,例如 kotlin_lib

    会出现一个新文件夹,其中包含一个 BUILD.BAZEL 文件。

  3. kotlin_lib 文件夹中,创建以下文件夹结构: src/main/com/example/mylib

  4. BUILD.BAZEL 移动到新创建的 src/main/com/example/mylib 中,并在其中添加以下代码:

    load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") package(default_visibility = ["//visibility:public"]) kt_jvm_library( name = "MyLib", srcs = ["MyLib.kt"] )

    与 Java 包类似,此代码:

    • 从 Kotlin 的 Bazel 规则(rules_kotlin )中导入 kt_jvm_library 规则。 这使 Kotlin JVM 库规则可在此 BUILD 文件中使用。

    • 将此包中目标的默认可见性设置为 public,这意味着项目中的任何其他 Bazel 包都可以依赖它们。

    • 在 Bazel 中声明一个名为 MyLib 的 Kotlin JVM 库目标。 该目标会将 MyLib.kt 编译为 JAR。

  5. src/main/com/example/mylib 中,创建名为 MyLib.kt 的文件,并填入以下内容:

    package com.example.mylib fun hello() = println("Hello from Kotlin")

同样,我们需要重新同步项目以应用更改。

重新同步项目

  • Bazel 工具窗口的工具栏上,单击 重新同步项目 按钮。

    Bazel 工具窗口工具栏上的 '重新同步项目' 按钮

从 Java 调用 Kotlin

要从 Java 包调用该 Kotlin 库,我们需要在相应的 BUILD.BAZEL 文件中为其添加依赖项。

为 Kotlin 包添加依赖项

  1. 打开 项目 工具窗口 Alt+1

  2. src/main/org/example/BUILD.bazel 文件中,将 deps 参数添加到 java_binary 调用中,如下所示:

    java_binary( name = "Main", main_class = "org.example.Main", srcs = glob(["**/*.java"]), deps = ["//kotlin_lib/src/main/com/example/mylib:MyLib"] )

然后,我们可以从 Java 包中调用 hello() 方法:

更新 Java 代码

  • src/main/org/example/Main.java 文件中,添加 导入 语句以及库函数调用,如下所示:

    package org.example; import com.example.mylib.MyLibKt; // import the library public class Main { public static void main(String[] args) { System.out.println("Hello World!"); MyLibKt.hello(); // call the library function } public static int constant4() { return 4; } }

然后,再次重新同步项目:

重新同步项目

  • Bazel 工具窗口的工具栏上,单击 重新同步项目 按钮。

    Bazel 工具窗口工具栏上的 '重新同步项目' 按钮

让我们运行该项目,并检查 Main Java 目标能否正确构建并运行。

构建并运行

  1. 在右侧边栏,单击 Bazel 图标。 您也可以从主菜单中选择 视图 | 工具窗口 | Bazel

  2. Bazel 工具窗口中,右键单击 Main 目标并选择 运行

    在 Bazel 工具窗口中右键单击 Main 目标时,会出现包含运行选项的上下文菜单

运行 工具窗口将打开并显示以下输出:

INFO: Build completed successfully, 1 total action INFO: Running command line: bazel-bin/src/main/org/example/Main Hello World! Hello from Kotlin

获取 JAR

到目前为止,我们一直直接在 IntelliJ IDEA 中运行该项目。 让我们找到可用于在其他位置运行该项目的 JAR 文件。

  1. 打开 项目 工具窗口 Alt+1

  2. 导航到 排除的目录 ,然后在 bazel-bin 下,找到与项目包结构相对应的目录。 在那里,您可以找到 Kotlin 库和主 Java 应用程序包的 JAR 文件。

    项目工具窗口中 bazel-bin 目录的内容

更改项目视图

此示例项目较小。 但是,如果您日后使用 Bazel 构建更大的项目,那么有一项功能在这种情况下会很有用。

Bazel 的 项目视图允许您隐藏不相关的包,仅处理当前需要的包。 这使源代码更易于导航,并减少对开发环境的负载,这在巨型 monorepos 中很重要。

让我们假设当前正在处理 Kotlin 库,并希望隐藏 Java 包。 这为我们提供了一个机会,来检验该功能的实际效果。

首先,我们需要创建一个 .bazelproject 文件。 这种类型的文件用于定义 Bazel 的项目视图包含的内容。

创建 .bazelproject 文件

  1. 打开 项目 工具窗口 Alt+1

  2. .bazelbsp 文件夹下,找到 .bazelproject 文件。

    .bazelbsp 文件夹中的 .bazelproject 文件

    其旁边的 已选择 标签表明这是当前正在使用的项目视图。

  3. 复制 .bazelbsp/.bazelproject 文件,并将其粘贴到项目根目录。

  4. 在新创建的 .bazelproject 文件中,将 目录 属性更改为指向 kotlin_lib 文件夹,如下所示:

    derive_targets_from_directories: true directories: kotlin_lib
  5. 项目 工具窗口中,右键单击此文件并选择 加载项目视图

    项目工具窗口中仅显示 kotlin_lib

    项目 工具窗口现在仅显示 kotlin_lib 包。

最后修改日期: 2025年 12月 2日