使用 IntelliJ IDEA 构建 Gradle 多模块的正确结构

Cra*_*tis 5 intellij-idea gradle kotlin

我有一个 Kotlin 项目,它由三个模块组成:

Core < Service < Web
Run Code Online (Sandbox Code Playgroud)

结构是:

build.gradle
core/
    build.gradle
service/
    build.gradle
web/
    build.gradle
Run Code Online (Sandbox Code Playgroud)

build.gradle文件的结构是:

buildscript {
    ext.kotlin_version = '1.1.60'
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
subprojects {
    apply plugin: 'kotlin'
    apply plugin: 'jacoco'
    compileKotlin {
        kotlinOptions.jvmTarget = '1.8'
    }
    repositories {
        mavenCentral()
        jcenter()
    }
}
Run Code Online (Sandbox Code Playgroud)

各个构建文件看起来像(对于core):

dependencies {
    // Kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    ...
}
Run Code Online (Sandbox Code Playgroud)

而对于service(注意唯一的区别是项目依赖):

dependencies {
    compile project (':core')
    // Kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想做一些优化,但我仍在学习 Gradle,并且找不到重新组织事物的正确方法。我遇到的问题是:

  1. 我无法构建serviceweb单独构建,因为他们抱怨无法找到他们依赖的子项目。(例如gradle build,通过service/目录中的a 。)

  2. 如何stdlib-jre8在根级别定义 Kotlin依赖项,使其不会在我的三个构建文件中重复?

  3. 我的根构建文件的子项目/构建脚本任务如何使用相同的存储库定义,以便我不必定义mavenCentral()/jcenter()两次?

基本上,我拥有的这个构建结构是通过一些实验/网络资源拼凑起来的,并且碰巧大部分工作,但我想要一些指导以正确的方式来做,这样(1)它遵循良好的 Gradle 实践,并且( 2) 通过自动导入到 IDEA 中仍然可以正常工作。

pab*_*sco 3

  1. 如果你想在模块上运行构建,你可以运行:gradle :web:build
  2. 与在子句中添加存储库的方式相同,您可以在其中subprojects添加块。dependencies确保其中只有共享依赖项。例如,compile project(':core')应该只在相关项目中。有多个块是可以的dependency。也就是说,使用该subproject条款通常更令人头疼。因为,如果其中一个模块的依赖关系发生变化,您将被迫更新所有模块的依赖关系
  3. repository定义来看,它们有很大不同。块中的内容buildscript由 Gradle 本身使用,以查找插件和其他“预构建”需求。子模块上的一个用于查找给定模块中源代码的依赖关系。正如上一点所提到的,当放置在各自的模块构建脚本上时,管理起来更容易。

更新:

如果您想为所有模块保留相同的版本,则构建脚本中定义的变量ext也应该能够从子模块访问:ext.kotlin_version = '1.1.60'如果您有多个变量,您可以添加它们,如下所示:

ext {
  kotlin_version = '1.1.60'
  junit_version = '4.12'
}
Run Code Online (Sandbox Code Playgroud)

另外,如果您想在模块之间共享代码,您可以随时将其提取到 gradle 文件并在需要时使用以下命令加载它:apply file: "$rootDir/path/to/script.gradle"

关于#3,我给你举一个实际的例子。

Google 有自己的 Maven 存储库,其中包含 Android 模块的所有依赖项。如果您的项目同时包含服务器端模块和 Android 模块,您可能不需要服务器端模块来查找 Gradle artefact 存储库上的依赖项(artefact 是 jar 依赖项的名称)。

至于buildscript存储库,在您的情况下,您仅加载位于的一个类路径(预构建)依赖项,mavenCentral()因此您可以jcenter()在此处删除。