Bzlmod 迁移指南

由于 WORKSPACE 存在 缺点,Bzlmod 将 取代旧版 WORKSPACE 系统。WORKSPACE 文件将在 Bazel 8(2024 年末)中默认停用,并在 Bazel 9(2025 年末)中移除。本指南可帮助您将项目迁移到 Bzlmod,并放弃使用 WORKSPACE 来 提取外部依赖项。

WORKSPACE 与 Bzlmod

Bazel 的 WORKSPACE 和 Bzlmod 提供类似的功能,但语法不同。本部分介绍了如何从特定的 WORKSPACE 功能迁移到 Bzlmod。

定义 Bazel 工作区的根目录

WORKSPACE 文件标记 Bazel 项目的源代码根目录,此职责 在 Bazel 6.3 及更高版本中由 MODULE.bazel 取代。对于 6.3 之前的 Bazel 版本,您的工作区根目录中仍应有一个 WORKSPACEWORKSPACE.bazel 文件,可能带有如下注释:

  • WORKSPACE

    # This file marks the root of the Bazel workspace.
    # See MODULE.bazel for external dependencies setup.
    

在 bazelrc 中启用 Bzlmod

借助 .bazelrc,您可以设置每次运行 Bazel 时应用的标志。如需启用 Bzlmod,请使用 --enable_bzlmod 标志,并将其应用于 common 命令,以便 它应用于每个命令:

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

为工作区指定代码库名称

  • WORKSPACE

    workspace 函数用于 为工作区指定代码库名称。这样,工作区中的目标 //foo:bar就可以引用为@<workspace name>//foo:bar。如果未指定,工作区的默认代码库名称为 __main__

    ## WORKSPACE
    workspace(name = "com_foo_bar")
    
  • Bzlmod

    建议使用 //foo:bar 语法引用同一工作区中的目标,而无需使用 @<repo name>。但是,如果您确实需要旧语法 ,则可以使用 module函数指定的模块名称作为代码库 名称。如果模块名称与所需的代码库名称不同,您 可以使用 repo_name 属性替换 module 函数的代码库名称。

    ## MODULE.bazel
    module(
        name = "bar",
        repo_name = "com_foo_bar",
    )
    

将外部依赖项提取为 Bazel 模块

如果您的依赖项是 Bazel 项目,并且它也采用 Bzlmod,那么您应该能够将其作为一 个 Bazel 模块依赖项。

  • WORKSPACE

    使用 WORKSPACE 时,通常使用 http_archivegit_repository 代码库规则 下载 Bazel 项目的源代码。

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "bazel_skylib",
        urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"],
        sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
    )
    load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
    bazel_skylib_workspace()
    
    http_archive(
        name = "rules_java",
        urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"],
        sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a",
    )
    load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
    rules_java_dependencies()
    rules_java_toolchains()
    

    如您所见,用户需要从依赖项的宏加载传递 依赖项是一种常见模式。假设 bazel_skylibrules_java 都依赖于 platformplatform 依赖项的确切版本由宏的顺序决定。

  • Bzlmod

    使用 Bzlmod 时,只要您的依赖项在 Bazel Central Registry 或自定义 Bazel registry 中可用,您就可以使用 bazel_dep 指令轻松地依赖它。

    ## MODULE.bazel
    bazel_dep(name = "bazel_skylib", version = "1.4.2")
    bazel_dep(name = "rules_java", version = "6.1.1")
    

    Bzlmod 使用 MVS 算法以传递方式解析 Bazel 模块依赖项。因此,系统会自动选择 platform 的最大所需版本。

替换 Bazel 模块的依赖项

作为根模块,您可以通过不同的 方式替换 Bazel 模块依赖项。

如需了解详情,请参阅替换部分。

您可以在 示例 代码库中找到一些使用示例。

使用模块扩展程序提取外部依赖项

如果您的依赖项不是 Bazel 项目,或者尚未在任何 Bazel 注册表中提供,您可以使用 use_repo_rule模块 扩展程序引入它。

  • WORKSPACE

    使用 http_file 代码库规则下载文件。

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    
  • Bzlmod

    使用 Bzlmod 时,您可以在 MODULE.bazel 文件中使用 use_repo_rule 指令直接实例化代码库:

    ## MODULE.bazel
    http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    

    在底层,这是使用模块扩展程序实现的。如果您需要 执行比简单调用代码库规则更复杂的逻辑,也可以 自行实现模块扩展程序。您需要将定义 移到 .bzl 文件中,这样您还可以在迁移期间在 WORKSPACE 和 Bzlmod 之间共享定义。

    ## repositories.bzl
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    def my_data_dependency():
        http_file(
            name = "data_file",
            url = "http://example.com/file",
            sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        )
    

    实现模块扩展程序以加载依赖项宏。您可以在宏的同一 .bzl 文件中定义 它,但为了与 旧版 Bazel 保持兼容,最好在单独的 .bzl 文件中定义它。

    ## extensions.bzl
    load("//:repositories.bzl", "my_data_dependency")
    def _non_module_dependencies_impl(_ctx):
        my_data_dependency()
    
    non_module_dependencies = module_extension(
        implementation = _non_module_dependencies_impl,
    )
    

    如需使代码库对根项目可见,您应在 MODULE.bazel 文件中声明 模块扩展程序和代码库的用法。

    ## MODULE.bazel
    non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies")
    use_repo(non_module_dependencies, "data_file")
    

使用模块扩展程序解决外部依赖项冲突

项目可以提供一个宏,该宏根据 调用者的输入引入外部代码库。但是,如果依赖项图中存在多个调用者,并且它们导致冲突,该怎么办?

假设项目 foo 提供以下宏,该宏将 version 作为 实参。

## repositories.bzl in foo {:#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
    http_file(
        name = "data_file",
        url = "http://example.com/file-%s" % version,
        # Omitting the "sha256" attribute for simplicity
    )
  • WORKSPACE

    使用 WORKSPACE 时,您可以从 @foo 加载宏,并指定所需的数据依赖项的版本 。假设您有另一个依赖项 @bar, 它也依赖于 @foo,但需要不同版本的数据 依赖项。

    ## WORKSPACE
    
    # Introduce @foo and @bar.
    ...
    
    load("@foo//:repositories.bzl", "data_deps")
    data_deps(version = "2.0")
    
    load("@bar//:repositories.bzl", "bar_deps")
    bar_deps() # -> which calls data_deps(version = "3.0")
    

    在这种情况下,最终用户必须仔细调整 WORKSPACE 中宏的顺序,才能获得所需的版本。这是 WORKSPACE 的最大痛点之一,因为它实际上没有提供解决依赖项的合理方法。

  • Bzlmod

    使用 Bzlmod 时,项目 foo 的作者可以使用模块扩展程序来解决 冲突。例如,假设在所有 Bazel 模块中始终选择数据依赖项的 最大所需版本是有意义的。

    ## extensions.bzl in foo
    load("//:repositories.bzl", "data_deps")
    
    data = tag_class(attrs={"version": attr.string()})
    
    def _data_deps_extension_impl(module_ctx):
        # Select the maximal required version in the dependency graph.
        version = "1.0"
        for mod in module_ctx.modules:
            for data in mod.tags.data:
                version = max(version, data.version)
        data_deps(version)
    
    data_deps_extension = module_extension(
        implementation = _data_deps_extension_impl,
        tag_classes = {"data": data},
    )
    
    ## MODULE.bazel in bar
    bazel_dep(name = "foo", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "3.0")
    use_repo(foo_data_deps, "data_file")
    
    ## MODULE.bazel in root module
    bazel_dep(name = "foo", version = "1.0")
    bazel_dep(name = "bar", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "2.0")
    use_repo(foo_data_deps, "data_file")
    

    在这种情况下,根模块需要数据版本 2.0,而其 依赖项 bar 需要 3.0foo 中的模块扩展程序可以正确 解决此冲突,并自动为数据 依赖项选择版本 3.0

集成第三方软件包管理器

在上一部分中,由于模块扩展程序提供了一种从依赖项图中收集 信息、执行自定义逻辑以解析 依赖项和调用代码库规则以引入外部代码库的方法,因此,这 为规则作者提供了一种很好的方式来增强集成 特定语言的软件包管理器的规则集。

如需详细了解如何使用模块扩展程序,请参阅模块扩展程序页面 。

以下是已采用 Bzlmod 从不同软件包管理器提取依赖项 的规则集列表:

示例代码库中提供了一个集成伪软件包管理器的最小示例。

检测主机上的工具链

当 Bazel 构建规则需要检测主机上可用的工具链时,它们会使用代码库规则检查主机,并将工具链信息生成为外部代码库。

  • WORKSPACE

    假设有以下代码库规则来检测 shell 工具链。

    ## local_config_sh.bzl
    def _sh_config_rule_impl(repository_ctx):
        sh_path = get_sh_path_from_env("SH_BIN_PATH")
    
        if not sh_path:
            sh_path = detect_sh_from_path()
    
        if not sh_path:
            sh_path = "/shell/binary/not/found"
    
        repository_ctx.file("BUILD", """
    load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain")
    sh_toolchain(
        name = "local_sh",
        path = "{sh_path}",
        visibility = ["//visibility:public"],
    )
    toolchain(
        name = "local_sh_toolchain",
        toolchain = ":local_sh",
        toolchain_type = "@bazel_tools//tools/sh:toolchain_type",
    )
    """.format(sh_path = sh_path))
    
    sh_config_rule = repository_rule(
        environ = ["SH_BIN_PATH"],
        local = True,
        implementation = _sh_config_rule_impl,
    )
    

    您可以在 WORKSPACE 中加载代码库规则。

    ## WORKSPACE
    load("//:local_config_sh.bzl", "sh_config_rule")
    sh_config_rule(name = "local_config_sh")
    
  • Bzlmod

    使用 Bzlmod 时,您可以使用模块扩展程序引入相同的代码库, 这与上一部分中引入 @data_file 代码库类似。

    ## local_config_sh_extension.bzl
    load("//:local_config_sh.bzl", "sh_config_rule")
    
    sh_config_extension = module_extension(
        implementation = lambda ctx: sh_config_rule(name = "local_config_sh"),
    )
    

    然后在 MODULE.bazel 文件中使用扩展程序。

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    

注册工具链和执行平台

在上一部分之后,在引入托管工具链 信息的代码库(例如 local_config_sh)后,您可能需要注册 工具链。

  • WORKSPACE

    使用 WORKSPACE 时,您可以通过以下方式注册工具链。

    1. 您可以在 .bzl 文件中注册工具链,并在 WORKSPACE 文件中加载宏。

      ## local_config_sh.bzl
      def sh_configure():
          sh_config_rule(name = "local_config_sh")
          native.register_toolchains("@local_config_sh//:local_sh_toolchain")
      
      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_configure")
      sh_configure()
      
    2. 或者直接在 WORKSPACE 文件中注册工具链。

      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_config_rule")
      sh_config_rule(name = "local_config_sh")
      register_toolchains("@local_config_sh//:local_sh_toolchain")
      
  • Bzlmod

    使用 Bzlmod 时, register_toolchainsregister_execution_platforms API 仅在 MODULE.bazel 文件中可用。您无法在模块扩展程序中调用 native.register_toolchains

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    register_toolchains("@local_config_sh//:local_sh_toolchain")
    

WORKSPACEWORKSPACE.bzlmod 和每个 Bazel 模块的 MODULE.bazel 文件中注册的工具链和执行平台在工具链选择期间遵循此 优先级顺序(从高到低):

  1. 在根模块的工具链和执行平台 MODULE.bazel文件中注册。
  2. WORKSPACEWORKSPACE.bzlmod 文件中注册的工具链和执行平台。
  3. 由根模块的 (传递)依赖项的模块注册的工具链和执行平台。
  4. 未使用 WORKSPACE.bzlmod 时:在 WORKSPACE 后缀中注册的工具链。

引入本地代码库

当您需要依赖项的 本地版本进行调试,或者想要将工作区中的 目录作为外部代码库纳入时,可能需要将依赖项作为本地代码库引入。

  • WORKSPACE

    使用 WORKSPACE 时,可以通过两个原生代码库规则 local_repositorynew_local_repository 实现此目的。

    ## WORKSPACE
    local_repository(
        name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    
  • Bzlmod

    使用 Bzlmod 时,您可以使用 local_path_override 将模块替换为本地路径。

    ## MODULE.bazel
    bazel_dep(name = "rules_java")
    local_path_override(
        module_name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    

    也可以使用模块扩展程序引入本地代码库。 但是,您无法在模块扩展程序中调用 native.local_repository, 我们正在努力将所有原生代码库规则 Starlark 化(如需了解进度,请查看 #18285)。 然后,您可以在模块 扩展程序中调用相应的 Starlark local_repository。如果这对您来说是一个阻碍性问题,那么实现 local_repository 代码库规则的自定义版本也很简单。

绑定目标

WORKSPACE 中的 bind 规则已废弃, 不支持该规则。引入该规则是为了在 特殊的 //external 软件包中为目标提供别名。所有依赖于此规则的用户都应迁移。

例如,如果您有

## WORKSPACE
bind(
    name = "openssl",
    actual = "@my-ssl//src:openssl-lib",
)

这样,其他目标就可以依赖于 //external:openssl。您可以通过以下方式迁移:

  • 将所有 //external:openssl 用法替换为 @my-ssl//src:openssl-lib

  • 或使用 alias 构建规则

    • 在软件包(例如 //third_party)中定义以下目标

      ## third_party/BUILD
      alias(
          name = "openssl",
          actual = "@my-ssl//src:openssl-lib",
      )
      
    • 将所有 //external:openssl 用法替换为 //third_party:openssl

提取与同步

提取和同步命令用于在本地下载外部代码库并使其保持最新状态 。有时,在提取构建所需的所有代码库后,还可以使用 --nofetch 标志离线构建。

  • WORKSPACE

    同步会对所有代码库或特定 配置的代码库集执行强制提取,而提取仅用于提取特定 目标。

  • Bzlmod

    同步命令不再适用,但提取提供了 各种选项。 您可以提取目标、代码库、一组配置的代码库或依赖项解析和模块扩展程序中涉及的所有 代码库。 提取结果会被缓存,如需强制提取,您必须在提取过程中添加 --force 选项。

迁移

本部分为您的 Bzlmod 迁移 过程提供了实用信息和指南。

了解 WORKSPACE 中的依赖项

迁移的第一步是了解您有哪些依赖项。由于传递依赖项通常使用 *_deps 宏加载,因此可能很难确定 WORKSPACE 文件中引入的确切依赖项。

使用工作区解析的文件检查外部依赖项

幸运的是,标志 --experimental_repository_resolved_file 可以提供帮助。此标志实际上会在您上次 Bazel 命令中生成所有提取的外部 依赖项的“锁定文件”。如需了解详情,请参阅这篇博文

它可以通过两种方式使用:

  1. 提取构建特定目标所需的外部依赖项的信息。

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. 提取 WORKSPACE 文件中定义的所有外部依赖项的信息。

    bazel clean --expunge
    bazel sync --experimental_repository_resolved_file=resolved.bzl
    

    借助 bazel sync 命令,您可以提取 WORKSPACE 文件中定义的所有依赖项,包括:

    • bind 用法
    • register_toolchainsregister_execution_platforms 用法

    但是,如果您的项目是跨平台的,则 bazel sync 可能会在某些 平台上中断,因为某些代码库规则可能仅在受支持的 平台上正确运行。

运行该命令后,您应该会在 resolved.bzl 文件中获得外部 依赖项的信息。

使用 bazel query 检查外部依赖项

您可能还知道 bazel query 可用于检查代码库规则

bazel query --output=build //external:<repo name>

虽然 bazel query 更方便且速度更快,但它可能会谎报 外部依赖项版本, 因此请谨慎使用!使用 Bzlmod 查询和检查外部 依赖项将通过新的 子命令实现。

内置默认依赖项

如果您检查 --experimental_repository_resolved_file 生成的文件, 您会发现许多未在 WORKSPACE 中定义的依赖项。 这是因为 Bazel 实际上会向用户的 WORKSPACE 文件内容添加前缀和后缀,以注入一些默认依赖项,这些依赖项通常是 原生规则(例如 @bazel_tools@platforms@remote_java_tools)所必需的。使用 Bzlmod 时,这些依赖项通过内置模块 bazel_tools 引入,该模块是每个其他 Bazel 模块的默认依赖项。

用于逐步迁移的混合模式

Bzlmod 和 WORKSPACE 可以并行运行,这样就可以逐步将依赖项 从 WORKSPACE 文件迁移到 Bzlmod。

WORKSPACE.bzlmod

在迁移期间,Bazel 用户可能需要在启用和 未启用 Bzlmod 的构建之间切换。为了使该 过程更顺畅,我们实现了 WORKSPACE.bzlmod 支持。

WORKSPACE.bzlmod 的语法与 WORKSPACE 完全相同。启用 Bzlmod 后, 如果工作区根目录中也存在 WORKSPACE.bzlmod 文件:

  • WORKSPACE.bzlmod 生效,WORKSPACE 的内容将被忽略。
  • 不会向 WORKSPACE.bzlmod 文件添加任何 前缀或后缀

使用 WORKSPACE.bzlmod 文件可以简化迁移,因为:

  • 停用 Bzlmod 后,您将回退到从 原始 WORKSPACE 文件提取依赖项。
  • 启用 Bzlmod 后,您可以更好地跟踪使用 WORKSPACE.bzlmod 迁移的剩余依赖项。

代码库可见性

Bzlmod 能够控制从给定 代码库中可以看到哪些其他代码库,如需了解详情,请查看 代码库名称和严格 依赖项

下面总结了在考虑 WORKSPACE 的情况下,不同类型的 代码库的代码库可见性。

来自主代码库 来自 Bazel 模块代码库 来自模块扩展程序代码库 来自 WORKSPACE 代码库
主代码库 可见 如果根模块是直接依赖项 如果根模块是托管模块扩展程序的模块的直接依赖项 可见
Bazel 模块代码库 直接依赖项 直接依赖项 托管模块扩展程序的模块的直接依赖项 根模块的直接依赖项
模块扩展程序代码库 直接依赖项 直接依赖项 托管模块扩展程序的模块的直接依赖项 + 由同一模块扩展程序生成的所有代码库 根模块的直接依赖项
WORKSPACE 代码库 全部可见 不可见 不可见 全部可见

迁移过程

典型的 Bzlmod 迁移过程可能如下所示:

  1. 了解 WORKSPACE 中的依赖项。
  2. 在项目根目录中添加一个空的 MODULE.bazel 文件。
  3. 添加一个空的 WORKSPACE.bzlmod 文件以替换 WORKSPACE 文件内容。
  4. 启用 Bzlmod 并构建目标,然后检查缺少哪些代码库 。
  5. 在解析的依赖项 文件中检查缺失的代码库的定义。
  6. 将缺失的依赖项作为 Bazel 模块引入,通过模块 扩展程序引入,或将其保留在 WORKSPACE.bzlmod 中以供日后迁移。
  7. 返回第 4 步并重复,直到所有依赖项都可用。

迁移工具

有一个交互式 Bzlmod 迁移 帮助脚本, 可帮助您入门。

该脚本执行以下操作:

  • 生成并解析 WORKSPACE 解析的文件。
  • 以易于理解的方式输出解析的文件中的代码库信息。
  • 运行 bazel build 命令,检测识别的错误消息,并推荐一种 迁移方式。
  • 检查依赖项是否已在 BCR 中可用。
  • 向 MODULE.bazel 文件添加依赖项。
  • 通过模块扩展程序添加依赖项。
  • 向 WORKSPACE.bzlmod 文件添加依赖项。

如需使用该脚本,请确保您已安装最新的 Bazel 版本,并运行以下 命令:

git clone https://github.com/bazelbuild/bazel-central-registry.git
cd <your workspace root>
<BCR repo root>/tools/migrate_to_bzlmod.py -t <your build targets>

发布 Bazel 模块

如果您的 Bazel 项目是其他项目的依赖项,您可以发布您的 项目在 Bazel Central Registry

如需在 BCR 中签入您的项目,您需要该项目的源代码归档网址。创建源代码归档时,请注意以下几点:

  • 确保归档指向特定版本。

    BCR 只能接受版本化的源代码归档,因为 Bzlmod 需要 在依赖项解析期间进行版本比较。

  • 确保归档网址稳定。

    Bazel 通过哈希值验证归档的内容,因此您应 确保下载文件的校验和永不更改。如果网址是 来自 GitHub,请在发布页面中创建并上传发布归档。 GitHub 不会保证按需生成的源代码归档的校验和。简而言之, https://github.com/<org>/<repo>/releases/download/... 形式的网址被认为是稳定的 而 https://github.com/<org>/<repo>/archive/... 则不是。如需了解更多背景信息,请参阅 GitHub 归档校验和 中断

  • 确保源代码树遵循原始代码库的布局。

    如果您的代码库非常大,并且您想通过剥离不必要的源代码来创建大小缩小的分发 归档,请确保剥离的源代码树是原始源代码树的子集。这样,最终用户就可以更轻松地通过 archive_overridegit_override 将模块替换为非发布 版本。

  • 在子目录中添加一个测试模块,用于测试最常用的 API。

    测试模块是一个 Bazel 项目,它有自己的 WORKSPACE 和 MODULE.bazel 文件,位于源代码归档的子目录中,该子目录依赖于要发布的 实际模块。它应包含涵盖最常用 API 的示例或一些 集成测试。如需了解如何设置 测试模块,请参阅测试模块。

准备好源代码归档网址后,请按照 BCR 贡献 指南,通过 GitHub 拉取请求将模块提交到 BCR。

强烈建议 为您的 代码库设置“发布到 BCR”GitHub 应用,以自动执行将模块提交到 BCR 的过程。

最佳实践

本部分介绍了一些最佳实践,您应遵循这些实践,以便更好地 管理外部依赖项。

将目标拆分为不同的软件包,以避免提取不必要的依赖项。

查看 #12835,其中测试的开发 依赖项被强制提取,而构建 目标不需要这些依赖项。这实际上并非 Bzlmod 特有的,但 遵循这些实践可以更轻松地正确指定开发依赖项。

指定开发依赖项

您可以为 bazel_depuse_extension 指令将 dev_dependency 属性设置为 true,这样 它们就不会传播到依赖项目。作为根模块,您可以使用 --ignore_dev_dependency 标志来验证您的目标 是否仍然在没有开发依赖项和替换的情况下构建。

社区迁移进度

您可以查看 Bazel Central Registry,了解您的依赖项是否已可用。否则,欢迎加入此 GitHub 讨论,为阻止您迁移的依赖项 投赞成票或发布这些依赖项。

报告问题

请查看 Bazel GitHub 问题列表,了解已知的 Bzlmod 问题。欢迎提交新问题或功能请求,以帮助您顺利完成 迁移!