gradle-node-plugin icon indicating copy to clipboard operation
gradle-node-plugin copied to clipboard

Add Project Dependency Configuration

Open myronu opened this issue 5 years ago • 6 comments

I'm trying to set up a multi-project Gradle build. We have a node (Angular) library, several Angular projects that depend on the library, and Spring Boot (Java) projects that will contain the final output. There are examples on the web for how to set up the node vs Java projects so that the node projects build first and their output is included in the WAR produced by the Java projects so that was pretty simple.

However, because the node plugin doesn't appear to declare any outputs or configurations, I am having problems getting node projects to depend on each other or the library. The Java plugin declares dependency configurations like readOnly, implementation, etc. If this plugin declares anything like that, I cannot figure out what it is.

Is there a way to make one node project depend on another node project?

myronu avatar Feb 24 '20 15:02 myronu

Where I work we use npm run dist to build our application, so we've got a npmRunDist task we depend on

deepy avatar Feb 24 '20 15:02 deepy

So this plugin provides an easy way to work with npm/yarn/etc, it doesn't build things itself like the java plugin does. I'm not actually certain how you'd accomplish what you want with npm, but what I can find suggest the following: Either use a file: link in your dependencies, or: Start by building the dependency, npm install it. Run npm link ../../path/to/your/dep

deepy avatar Feb 25 '20 08:02 deepy

I was able to use gradle configurations to set up the proper dependencies to work around this. It works like this:

  1. Declare a configuration in your base script
configurations {
    npmResources {
      canBeResolved = true
      canBeConsumed = true
    }
  1. Make the library build depend on the folder containing its build output (note libBuildDir is not a standard variable, but one I defined):
dependencies {
  npmResources fileTree("${libBuildDir}/") {
    builtBy 'buildLib'
  }
}
  1. Make your client project depend on the output of the lib project:
dependencies {
  npmResources project(path: ':projects:my-library', configuration: 'npmResources')
}
  1. Make npmInstall depend on the lib project:
npmInstall.dependsOn(configurations.npmResources)

myronu avatar Feb 25 '20 14:02 myronu

Personnally, I use a different approach to do that. I make a jar including the webapp in its resources and I add an implementation dependency to this jar to get this in the global application build.

Your suggestion seems to be more elegant than mine, but there is something I don't understand (I don't know very well how the Gradle configurations work). Is the npmResources configuration automatically embedded in the global application jar or war or do you have to add anything to get it done?

bsautel avatar Feb 26 '20 08:02 bsautel

I don't think any plugin defines npmResources. You can declare configurations on the fly, which is what I'm doing. Adding the dependency in the way I did it lets the downstream project depend on it and include it. In my WAR task I was able to do something like this to get the Node output into my WAR where Spring Boot could find it:

from (configurations.npmResources) { into 'WEB-INF/classes/static' }

Please note that I actually used a different configuration that depended on the output of npm_run_build since npmResources was used for my library project, but it works the same.

myronu avatar Mar 02 '20 14:03 myronu

Ok, thank you! Now I understand how you proceed and that's very elegant!

I read again your original question and as far as I understand, your problem with this configuration is that when you build the main Spring Boot application, it does not automatically trigger a build of the web project?

bsautel avatar Mar 05 '20 14:03 bsautel