What is the difference between maven and npm respository? - node.js

I want to know the differences between npm and maven respository

Same tool, different language?
Maven is the most popular build and dependency resolution tool for Java, just like NPM is for JS. But it's not just the same tool for a different language. There are obviously huge differences between Java and JS builds, and these differences are directly visible in the way Maven operates. For example, while many JS tools rely on Git to do some heavy-lifting, Maven works with custom filesystem-based Maven repositories, as Maven predates Git and needs to handle binary artifacts, which Git historically didn't handle well. In Maven there's a clear separation between sources and binaries, while they are often the same thing in JS world.
Maven basics
Maven in its purest form follows a declarative model, where pom.xml (similar to package.json) defines different properties of the build, but contains no scripts. The disadvantage is it can be a challenge to fine-tune some aspects of the build without using scripts as you have to rely on plugins. The advantage is it can be easier to understand other builds just by looking at pom.xml, as they usually follow the same approach without too much customization. Gradle is a popular Groovy-based tool built on top of Maven standards and conventions, and is specifically designed to simplify pom.xml and break this "no script" barrier.
Referencing your dependencies
Similarly to package.json, you don't work with pom.xml of your dependency directly, but rather define dependency coordinates and let your build tool handle the rest. In Maven the basic form of these coordinates is GAV (groupId, artifactId, version).
Flat dependency tree?
Based on comments in the other answer, Maven provides "flat dependency tree", not "nested dependency tree" that NPM provides by default. Maven does not allow multiple versions of the same dependency. If it happens that different versions are requested, Maven uses dependency resolution to pick a single version. This means that sometimes your transitive dependencies will get a different version than they require, but there are ways to manage this. However, this limitation comes from Java, not Maven, as (normally) in Java a class loader will only provide access to a single class definition even if multiple definitions are found on the classpath. Since Java is not particularly good at handling this, Maven tries to avoid this scenario in the first place.
Note: since npm v3 the dependencies are flatten. The alternative package manager yarn also does the same.
Maturity
Furthermore, Maven is considerably older than NPM, has a larger user base, huge number of custom plugins, and so far could probably be considered more mature overall. Sometimes Maven is used for non-Java or even polyglot projects, as there are plugins for handling other languages or specific environments, such as Android. There are plugins that bridge Maven and other build tools, such as frontend-maven-plugin that actually handles multiple JS build tools.

NPM is focused on JavaScript while Maven is focused on Java and JVM derived (that is Scala, Kotlin, Groovy).
So comparing them doesn't make sense at all as these are not concurrent.
While comparing Maven to Gradle (Java world concurrent) or NPM to Yarn (JavaScript world concurrent) makes more sense.
Now Maven and NPM have closed features. Which is not surprising : good recipes spread beyond a language.
Here are some common points/features:
- these are package(JavaScript term)/ dependency (Maven term) managers that works with local/remote repositories.
- these are also a way to manage dependencies in your projects and to execute build tasks for them.

Related

What is the simplest way to share react components between projects?

How can I share components across multiple react projects without having to publish them on a public package manager like NPM?
Option 1: You can use npm and use private packages so they're not external facing. There are also artifactories and scoped packages that usually represent company-wide projects that can be public or private. See https://docs.npmjs.com/private-modules/intro and https://docs.npmjs.com/misc/scope.
Option 2: Essentially, you can develop projects with a flattened structure. You can then import various projects and/or components into other projects or folders. This is entirely dependent on your codebase and configuration. With this model though, a lot of times publishing to npm comes fairly naturally since each folder may be its own project with its own package.json.
Updated:
Option 3: Bit focuses on the composability of components from everything from the little things like a button to the actual view and app itself—each target is its own package. Overall, it's an opinionated, yet customizable framework that can enable quicker development, managed dependencies, and organized code.
Option 4: RushJS is a monorepo manager built by Microsoft that allows for flexibility of different kinds of apps and services utilizing pnpm underneath (as opposed to yarn and npm), which alleviates problems that stem from dependency issues.
Check out Bit:
Bit is an open-source cli tool for collaborating on isolated components across projects and repositories. Use Bit to distribute discrete components from a design library or a project into a standalone reusable package and utilize it across applications.
You could also upload them to a private git repo such a Github and then pull them in from there.
Ryanve has a nice example over here: https://stackoverflow.com/a/28729646/1592783
You could create a repo of shared components and then have your Node.js start script call a shell script to do a git pull from that repo and the move the shared components from that directory to your project's directory. That way, every time you call run 'npm start' you will have the latest version of the shared components loaded into your project

Is updating npm dependencies not recommended on a production application?

I recently started exploring npm and installed a github repo yoonic/nicistore.
But when I try to build it fails.
My question is if I start building things on top of node, which I see has tooo many dependencies from different vendors, Am I completely on the mercy of the respective package developers?
I have seen that most node based github repos fail to build in the first try. If I update one of the modules by running a console command, Is it likely to break all the application?
And if It is does, doesn't it prove node.js an unreliable and unstable development platform?
Think of it as the opposite of most other languages.
You are writing an app in Java.
You want to use LibA, LibB and LibC.
So you try to use LibC 2.4, and as soon as you do, your manager throws all kinds of errors at you.
Why?
Because LibB is using LibC 1.9
So now what are your options?
Strip out all of the calls to all of the new API for LibC that you wanted to use...
...or hope that LibB is open-source, and you can contribute an update for a new version of it, so that you can use the latest version of LibC (and hope it doesn't update).
So now you've done that... but now you've broken your LibA, because it wants the old LibB.
You didn't even want LibA, you just had to have it for your app to be happy with your framework, and the libs that you did actually want to use (B and C). LibA is closed-source, and isn't maintained, anymore. Tough luck. Go back to your old ways, and forget about how much better life could be, if you could only use your framework with the new version of LibC. Or start praying that your framework does a major rewrite, to get rid of the LibA dependency... but then figure out what new hell you have to deal with, just to get LibC working.
Is this really better than Node?
What node allows you to do is install dependencies which are at different versions than the same library that your dependencies are using.
Not that you can't do that with Java, too... but the entire community has decided that it's just not ever going to try to do that, and thus outlaw it at a tool level.
Next, you see too many things which leave you at the mercy of too many vendors...
Going back to Java (or C++, or nearly any mainstream language), looking at Java, itself, how many libraries are made by Sun Microsystems, or by James Gosling?
Moreover, if you want to boil it down, to suggest using only, say, one huge, overarching framework (like Spring MVC) and using no other libraries of any kind (like JodaTime), then how many libraries does Spring itself lean on, and why are they of no concern to you, even if you're just using the compiled VM bytecode?
In fact, a strong argument could be made to be more wary of compiled binaries, in languages where it was traditional to see strong, copy-left licensing like that of the GNU GPL... in that realm, you open yourself up to craziness.
Most of the Node stuff, by comparison, is dirt-simple freeware. And even if it's not, it's quickly replaceable as most are micro-libraries.
I would suggest that updating a Node package your server depends on, via CLI is less hazardous than doing the same to a full-fledged Java project, if your goal is to see your project compile again, some time in the next week, but with the newer fixes/features...
...but if you're talking about a full-scale, production application, you also want to be cognizant of what it is you're doing, with regards to your codebase, regardless.
As to why things don't build for you on the first try, assuming that you're on a non-Windows platform, and your environment is up to date, I don't know.
Most C/C++ projects I clone don't build for me, first try, either. I usually forget something, or there was something poorly documented, or the actual project was set up to make unfair assumptions about the system it would operate in.
Does that mean that C++ is an unreliable/unstable development platform?
Or the hours/days spent on getting Eclipse set up in an enterprise environment, with all kinds of crazy, company-specific projects and project settings?
It sounds like a case of bad design, more than anything.
Then again, most of my projects these days are wrapped in Docker containers. They all run in the same environment, whether they're running in Windows, on a Mac, or on the server. That tends to take the sting out of building projects, regardless of what language the code is in, or what VM / processor they're running on.
You should also be using NPM shrinkwrap files, or Yarn Lockfiles to preserve the build configuration, with the known-working versions of libraries. And you should have unit and integration tests to ensure that changing library versions has no discernible impact on your system.

dependency-check for application code

I am looking for a solution to implement security-scanning of the application code-base at the time of a build. The idea is to capture a list of security vulnerabilities early in the software development life cycle.
I have a simple java project which uses a maven build. The java project specifies a number of .jar dependencies and comes up with a .war file as a build output.
I came across (and was able to configure) the dependency-check maven plugin (http://jeremylong.github.io/DependencyCheck/dependency-check-maven/index.html). However, though it scans the dependency jars and comes up with a vulnerability report, it doesn't seem to scan the final artifact - which in my case is the .war file.
How do I ensure that the .war is scanned as well? Is the dependency-check plugin the right tool for this?
dependency-check isn't the right tool for checking your own code. It uses a list of known vulnerability reports to determine if any of your dependancies have known flaws. It does not do an active scan of the code. see Plugin wiki
For checking your own code, HP's Fortify is a decent commercial solution, but if you are working in more of a DIY software setting, I would recommend Sonar. There are certainly many static code analysis tools out there. All have advantages and disadvantages.

import common dependencies to package.json?

At our company we have at the moment 5 web applications that are built using Gulp. For Gulp, we have a common buildfile that all applications use (and override certain parts of it if needed).
This makes it very easy to add features or fix bugs in all projects at the same time. However, I still need to edit the package.json file in each project separatly if I want to add a new npm dependency or bump a version for an existing one.
What I would like to accomplish is to a "base file" where all the common dependencies are configured, and the I would like to import that into the "local" package.json in each project. It would also be nice if each project could add more dependencies than the ones registered as common.
Is it possible to do this?
No, and it's a good thing that it isn't. You need to declare your dependencies explicitly on each project.
What you can do, if your build process is a shared API, is to extract your build script into an npm package of its own, and include that in the package.json of all other projects, and use it in them (coding it in a way that allows for overrides)
Then when you need a new dependency for your common build, you only need to change it once. (Note that with this, you'd still need to make sure your build package version is up to date in all other applications)

Downloading Dependences From Private Amazon S3 Repository with Gradle

I am looking to add Groovy support to an existing java project so that I can seemlessly compile mixed Java and Groovy code using invokedynamic so that I can get Java-like execution speed without needing to waste excessive amounts of time with verbose Java syntax
After reading that the gmaven plugin no longer supports compilation -and that the groovy eclipse compiler plugin doesn't yet support invokedynamic, I asked myself, why would I want to continue using Maven if it compiles Groovy code that is needlessly slow?
Consequently, I decided I would try scrapping maven for Gradle so that I could obtain faster code while also porting some python deployment scripts to Gradle tasks so as to only need one codebase.
I have some libraries stored on a simple password protected s3 maven repository (in order to avoid needing enterprise overkill like artifactory). After doing some basic research, I have found that Gradle has no built in support for adding in custom dependency management as determined by this stack overlow question and this support forums post.
I did manage to find a s3 plugin for gradle -but it doesn't deal with management of dependencies.
If the whole point of Gradle is to be more flexible than Maven and if the core purpose of a dependency management/ build system is to effectively manage dependencies from a variety of sources-then lack of support for custom repositories appears to be a fairly significant significant design flaw which makes any issues I have encounted with Maven thus far pale in comparison.
However, it is quite possible that I am missing something, and I have already invested several hours learning Gradle -so I figured I would see if there is some reasonable way to emulate dependency management for these s3 dependencies until Gradle developers fix this critical issue. Otherwise I will have to conclude that I am better off just using Maven and tolerating slower Groovy code until the compiler plugin supports invokedynamic.
Basically I need a solution that does the following:
Downloads dependencies and transitive dependencies to the gradle cache
Doesn't require me to hardcode the path to the gradle cache -so that my build script is platform independent.
Doesn't download the dependencies again if they are already in the cache.
Works with a multi-module project.
However, I cannot find anything in the documentation that would even give me a clue as to where to begin:
Gradle 2.4 has native support for S3 repositories. Both downloading dependencies and publishing artifacts.
To download with IAM credentials (paraphrased from the link above):
repositories {
maven {
url "s3://someS3Bucket/path/to/repo/root"
credentials(AwsCredentials) {
accessKey 'access key'
secretKey 'secret key'
}
}
}
Then specify your dependencies as usual.
You don't need any custom repository support to make this work. Just declare a maven repository with the correct URL. If the repository works when used from Maven, it will also work with Gradle. (Uploading may be a different matter.)
You can use S3 and http
repositories {
mavenCentral()
ivy {
url "https://s3-eu-west-1.amazonaws.com/my-bucket"
layout "pattern", {
artifact "[artifact]-[revision].[ext]"
m2compatible = true
}
}
}
Name the jar in S3 to name-rev.jar (joda-time-3.2.jar) in my-bucket.
Also upload a pom file.
And in S3 give all permission to Download the jar and pom.

Resources