mvnpm / mvnpm

Use npm like any other Maven/Gradle dependency...
https://mvnpm.org/
Apache License 2.0
18 stars 6 forks source link
gradle java maven npm

Logo

Use npm like any other Maven dependency...

mvnpm (Maven NPM) allows to consume the NPM Registry packages as dependencies directly from a Maven project:

    <dependency>
        <groupId>org.mvnpm</groupId>
        <artifactId>{package-name}</artifactId>
        <version>{package-version}</version>
        <scope>{runtime/provided}</scope>
    </dependency>

or from a Gradle project:

dependencies {
    runtimeOnly/compileOnly("org.mvnpm:{package-name}:{package-version}")
}

Use org.mvnpm.at.{namespace} as groupId for a particular namespace (i.e. @hotwired/stimulus becomes org.mvnpm.at.hotwired:stimulus).

How to consume?

How to sync a missing package?

A lot of packages are already synced on Central, which mean they can directly be used from you pom.xml or build.gradle. You may check if a package version is available by looking at the "Maven central" badge on the Browse page. If it's not:

You should use the Maven Central repository for production builds.

How to configure the fallback repository?

The mvnpm Maven repository is a facade on top of the NPM Registry, it is handy when starting (or updating versions) on a project with many non synchronised packages (which will become more and more unlikely in the future).

Maven

To use it in your local Maven settings add the following to your settings.xml (typically /home/your-username/.m2/settings.xml)

    <settings>
    <profiles>
        <profile>
            <id>mvnpm-repo</id>
            <repositories>
                <repository>
                    <id>central</id>
                    <name>central</name>
                    <url>https://repo.maven.apache.org/maven2</url>
                </repository>
                <repository>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                    <id>mvnpm.org</id>
                    <name>mvnpm</name>
                    <url>https://repo.mvnpm.org/maven2</url>
                </repository>
            </repositories>
        </profile>
    </profiles>

    <activeProfiles>
        <activeProfile>mvnpm-repo</activeProfile>
    </activeProfiles>

</settings>

Gradle

The mvnpm repository can be configured as any other repositories in your project. Since Gradle honnors the repository order when fetching dependencies, it is recommended to declare it after maven-central. This way it will only be used as fallback, when the dependency is absent from maven-central. In addition it is a good practice to configure repository content filtering to help Gradle to understand which dependencies can be fetched from the mvnpm repository and avoid uncessary lookups.

repositories {
    mavenCentral()
    maven {
        name = "mvnpm"
        url = uri("https://repo.mvnpm.org/maven2")
        content {
            includeGroupByRegex "org\\.mvnpm.*"
        }
    }
}

How does the mvnpm Maven repository work ?

Schema

How to update versions?

mvnpm continuously monitor the NPM Registry for any previously synchronized packages. When it detects a new version, a synchronization process will be initiated. So tools like dependabot will be able to propose the new version in your pull requests.

How to lock dependencies?

Locking with Maven

The mvnpm locker Maven Plugin will create a version locker profile for your org.mvnpm and org.webjars dependencies. Allowing you to mimick the package-lock.json and yarn.lock files in a Maven world.

It is essential as NPM dependencies are typically deployed using version ranges, without locking your builds will use different versions of dependencies between builds if any of your transitive NPM based dependencies are updated.

In addition when using the locker, the number of files Maven need to download is considerably reduced as it no longer need to check all possible version ranges (better for reproducibility, contributors and CI).

Locking with Gradle

Gradle provides a native version locking system, to install it, add this:

build.gradle

dependencyLocking {
    lockAllConfigurations()
}

Then run gradle dependencies --write-locks to generate the lockfile.