diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt index 7fab70a7660..d81fa19341f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt @@ -67,20 +67,22 @@ open class NodeJsRootPlugin : Plugin { it.gradleNodeModules.set(gradleNodeModulesProvider) } - val npmInstall = project.registerTask(KotlinNpmInstallTask.NAME) { - it.dependsOn(setupTask) - it.dependsOn(setupFileHasherTask) - it.group = TASKS_GROUP_NAME - it.description = "Find, download and link NPM dependencies and projects" + val npmInstall = project.registerTask(KotlinNpmInstallTask.NAME) { npmInstall -> + npmInstall.dependsOn(setupTask) + npmInstall.dependsOn(setupFileHasherTask) + npmInstall.group = TASKS_GROUP_NAME + npmInstall.description = "Find, download and link NPM dependencies and projects" - it.onlyIfCompat("No package.json files for install") { task -> + npmInstall.onlyIfCompat("No package.json files for install") { task -> task as KotlinNpmInstallTask task.preparedFiles.all { file -> file.exists() } } - it.doNotTrackStateCompat("NPM package manager track by its own") + npmInstall.outputs.upToDateWhen { + npmInstall.nodeModules.exists() + } } project.registerTask(PACKAGE_JSON_UMBRELLA_TASK_NAME) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt index e36d7bd2ab5..43b39e1a4f7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt @@ -75,6 +75,8 @@ internal class GradleNodeModuleBuilder( packageJson.main = "${name}.js" } + packageJson.devDependencies.clear() + // yarn requires semver packageJson.version = fixSemver(packageJson.version) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt index 01e1ff29402..3c1346e68bf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager import org.jetbrains.kotlin.gradle.targets.js.npm.UsesKotlinNpmResolutionManager import org.jetbrains.kotlin.gradle.targets.js.npm.asNpmEnvironment import org.jetbrains.kotlin.gradle.targets.js.npm.asYarnEnvironment +import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn import java.io.File @@ -33,6 +34,9 @@ abstract class KotlinNpmInstallTask : private val yarn get() = project.rootProject.yarn + private val rootResolver: KotlinRootNpmResolver + get() = nodeJs.resolver + // ----- private val npmEnvironment by lazy { @@ -54,11 +58,29 @@ abstract class KotlinNpmInstallTask : nodeJs.packageManager.preparedFiles(npmEnvironment) } + @get:PathSensitive(PathSensitivity.RELATIVE) + @get:IgnoreEmptyDirectories + @get:NormalizeLineEndings + @get:InputFiles + val packageJsonFiles: Collection by lazy { + rootResolver.projectResolvers.values + .flatMap { it.compilationResolvers } + .map { it.compilationNpmResolution } + .map { it.npmProjectPackageJsonFile } + } + @get:OutputFile val yarnLock: File by lazy { nodeJs.rootPackageDir.resolve("yarn.lock") } + // node_modules as OutputDirectory is performance problematic + // so input will only be existence of its directory + @get:Internal + val nodeModules: File by lazy { + nodeJs.rootPackageDir.resolve("node_modules") + } + @TaskAction fun resolve() { npmResolutionManager.get()