1. 组织构建

组织构建 

本页讨论构建结构的组织方式。

请先阅读入门指南中的前面几页,特别是你需要了解 build.sbt任务图库依赖项多项目构建,然后再阅读本页。

sbt 是递归的 

build.sbt 隐藏了 sbt 的实际工作原理。sbt 构建是使用 Scala 代码定义的。该代码本身需要构建。有什么比 sbt 更好的构建方法呢?

project 目录是构建内部的另一个构建,它知道如何构建你的构建。为了区分这些构建,我们有时使用适当构建来指代你的构建,并使用元构建来指代 project 中的构建。元构建中的项目可以做任何其他项目可以做的事情。你的构建定义是一个 sbt 项目。

而且乌龟一直往下延伸。如果你愿意,你可以通过创建 project/project/ 目录来调整构建定义项目的构建定义。

这是一幅图示。

hello/                     # your build's root project's base directory

    Hello.scala            # a source file in your build's root project
                           #   (could be in src/main/scala too)

    build.sbt              # build.sbt is part of the source code for
                           #   meta-build's root project inside project/;
                           #   the build definition for your build

    project/               # base directory of meta-build's root project

        Dependencies.scala # a source file in the meta-build's root project,
                           #   that is, a source file in the build definition
                           #   the build definition for your build

        assembly.sbt       # this is part of the source code for
                           #   meta-meta-build's root project in project/project;
                           #   build definition's build definition

        project/           # base directory of meta-meta-build's root project;
                           #   the build definition project for the build definition

            MetaDeps.scala # source file in the root project of
                           #   meta-meta-build in project/project/

别担心!大多数情况下,你不需要使用所有这些功能。但理解这个原理可能会有所帮助。

顺便说一下:在使用以 .scala.sbt 结尾的文件时,将它们命名为 build.sbtDependencies.scala 仅仅是约定。这也意味着允许多个文件。

在一个地方跟踪依赖项 

使用 project 下的 .scala 文件成为构建定义的一部分这一事实的一种方法是创建 project/Dependencies.scala 来在一个地方跟踪依赖项。

import sbt._

object Dependencies {
  // Versions
  lazy val akkaVersion = "2.6.21"

  // Libraries
  val akkaActor = "com.typesafe.akka" %% "akka-actor" % akkaVersion
  val akkaCluster = "com.typesafe.akka" %% "akka-cluster" % akkaVersion
  val specs2core = "org.specs2" %% "specs2-core" % "4.20.0"

  // Projects
  val backendDeps =
    Seq(akkaActor, specs2core % Test)
}

Dependencies 对象将在 build.sbt 中可用。为了更方便地使用其中定义的 val,在你的 build.sbt 文件中导入 Dependencies._

import Dependencies._

ThisBuild / organization := "com.example"
ThisBuild / version      := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.12.18"

lazy val backend = (project in file("backend"))
  .settings(
    name := "backend",
    libraryDependencies ++= backendDeps
  )

当你的多项目构建变得很大,并且你想要确保子项目具有一致的依赖项时,此技术很有用。

何时使用 .scala 文件 

.scala 文件中,你可以编写任何 Scala 代码,包括顶层类和对象。

推荐的做法是在多项目 build.sbt 文件中定义大多数设置,并在 project/*.scala 文件中定义任务实现或共享值,例如键。.scala 文件的使用还取决于你或你的团队对 Scala 的熟悉程度。

定义自动插件 

对于更高级的用户,组织构建的另一种方法是在 project/*.scala 中定义一次性 自动插件。通过定义触发插件,自动插件可以作为一种方便的方式,将自定义任务和命令注入到所有子项目中。