When publishing can I replace "link:../dir" with the version of the package being linked with? - node.js

In my package.json I have
"dependencies": {
"components": "link:../components",
"react": "^16.9.0",
"react-dom": "^16.9.0"
}
This works fine during development, however when trying to publish the packages to npm the "link:../components" is published into the package.
Is there a way to take the "link:../components" and replace it with the version of the package.json in the file it's being linked with?
basically
"dependencies": {
"components": "link:../components",
"react": "^16.9.0",
"react-dom": "^16.9.0"
}
would convert to
"dependencies": {
"components": "1.2.3",
"react": "^16.9.0",
"react-dom": "^16.9.0"
}
before being published to npm. The linked dependency would remain locally, though.

npm link is a development utility to test your npm packages before you publish them.
https://docs.npmjs.com/cli/link
Using your example names, say you are developing a npm package components. While you are developing it, you want to test it in your main project (The consumer of your package).
The way to go about this is, to go in your components package dir, and run npm link, this will create a global link in your system that will make it available to other projects.
So now you can go in your main project dir, and run npm link components (components is the name of your package, not to be confused with dir name)
This is fine during development, but of course won't work when you publish your packages.
Is there a way to take the "link:../components" and replace it with the version of >the package.json in the file it's being linked with?
First publish components package to npm (A good
article
that explains it)
In your main project dir, run npm unlink
components.
This will remove the global link to components in your
project dir.
In your main project dir, run npm install components.
This will fetch components from npm.

Related

npm install is not adding all dependencies

I issue npm install protractor.
Under /path/to/node_modules/protractor/node_modules, i was expecting all the internal dependencies of protractor npm. But i am seeing only one module, q.
However in /path/to/node_modules/protractor/package.json, i can see all dependencies of protractor listed as,
"dependencies": {
"adm-zip": "0.4.4",
"glob": "~3.2",
"jasmine": "2.3.2",
"jasminewd2": "0.0.6",
"lodash": "~2.4.1",
...................
}
Protractor module is versioned "3.0.0" and npm is versioned 3.3.12, node.js is versioned v5.1.0.
What has changed in these new versions? Since, all npm modules used to maintain their own dependency copies.
npm 3 flattens the dependency tree, so you should see protractor's dependencies in /path/to/node_modules.
If you don't see them there, my first guess is that you might have an npm-shrinkwrap.json file that is preventing modules from being installed, so you could check for that.

nodejs project dependencies synchronization

I am creating a nodejs project and wish to have same library versions used across dev, qa, staging and production environment.
Tried package.json but was unable to find good help. Need some suggestion here.
EDITED
{
"dependencies": {
"ioredis": "1.7.5",
"redis": "0.12.1",
"redis-hash": "0.0.4",
"debug": "*"
}
}
Specify your dependencies using the exact versions in the package.json file, and when you run npm install it will get the proper versions of all your dependencies.
If you don't specifiy an exact version for the libraries, there's a chance that there's a new version since the last time you ran the command, you will end up with different versions of your libraries on your servers, which might not be what you want.
NPM has an outdated command which will list all the dependencies that have fallen behind and need to be updated. You can then run npm install.

npm private modules error

I've couple of private modules that are not on the npm site and I'd like to use them in my application but running in couple of issues while uploading at Elasticbeanstalk. (Elastic beanstalk runs it's npm install after each upload).
The AWS complained initially that it couldn't find those private modules on NPM, so I removed their entries from package.json file.
Once I removed, I uploaded the application again with node_modules folder having those packages then AWS start to complain
Error: Cannot find module 'my-private-module-name'
I'm wondering how private modules work so I don't have to go through NPM at least for deployment or as a last resort I'll publish them.
Edit
"dependencies": {
"body-parser": "^1.12.4",
"express": "^4.12.3",
"multer": "^0.1.8",
"mustache": "^2.0.0",
"mysql": "^2.6.2",
"my-private-module": "^1.0.5",
"redis": "^0.12.1",
"socket.io": "^1.3.3"
},
You will need to have an internal way of publishing packages if you wish to not have certain packages looked up on npm.
In your individuals packages you will need to add
"publishConfig":{"registry":"http://my-internal-registry.local"}
to the package.json file.
This will allow you to look up packages at that location as opposed to going directly to NPM.
https://docs.npmjs.com/misc/registry
Then in your ~/.npmrc file you can specify a registry that npm will use first prior to looking up modules on npm.

Install multiple Node.js Modules based on dependencies (list)

I have a dependencies list of nearly 40 node modules and while I was able to install all of them using one (or two) commands-
npm install module-1 module-2 ... module-N --save-dev
-still looking for a way to create a file that installs all dependencies when executed. This way anyone could download a single file for his/her system (Mac / Linux in my case) and install all modules by simply running that file. Any great suggestion, method? Thanks a lot!
npm init will create a package.json for you. Within that file you can list your app's dependencies and dev dependencies like this:
{
...
"dependencies": {
"express": "^4.9.7"
},
"devDependencies": {
"mocha": "^2.0.1"
}
}
Then npm install

Why use peer dependencies in npm for plugins?

Why does, for example, a Grunt plugin define its dependency on grunt as "peer dependencies"?
Why can't the plugin just have Grunt as its own dependency in grunt-plug/node_modules?
Peer dependencies are described here: https://nodejs.org/en/blog/npm/peer-dependencies/
But I don't really get it.
Example
I'm working with AppGyver Steroids at the moment which uses Grunt tasks to build my source files into a /dist/ folder to be served on a local device. I'm quite new at npm and grunt so I want to fully comprehend what is going on.
So far I get this:
[rootfolder]/package.json tells npm it depends on the grunt-steroids npm package for development:
"devDependencies": {
"grunt-steroids": "0.x"
},
Okay. Running npm install in [rootfolder] detects the dependency and installs grunt-steroids in [rootfolder]/node_modules/grunt-steroids.
Npm then reads [rootfolder]/node_modules/grunt-steroids/package.json so it can install grunt-steroids own dependencies.:
"devDependencies": {
"grunt-contrib-nodeunit": "0.3.0",
"grunt": "0.4.4"
},
"dependencies": {
"wrench": "1.5.4",
"chalk": "0.3.0",
"xml2js": "0.4.1",
"lodash": "2.4.1"
},
"peerDependencies": {
"grunt": "0.4.4",
"grunt-contrib-copy": "0.5.0",
"grunt-contrib-clean": "0.5.0",
"grunt-contrib-concat": "0.4.0",
"grunt-contrib-coffee": "0.10.1",
"grunt-contrib-sass": "0.7.3",
"grunt-extend-config": "0.9.2"
},
The "dependencies" packages are installed into [rootfolder]/node_modules/grunt-steroids/node_modules which is logical for me.
The "devDependencies" aren't installed, which I'm sure is controlled by npm detecting I'm just trying to use grunt-steroids, and not develop on it.
But then we have the "peerDependencies".
These are installed in [rootfolder]/node_modules, and I don't understand why there and not in [rootfolder]/node_modules/grunt-steroids/node_modules so that conflicts with other grunt plugins (or whatever) are avoided?
TL;DR: peerDependencies are for dependencies that are exposed to (and expected to be used by) the consuming code, as opposed to "private" dependencies that are not exposed, and are only an implementation detail.
The problem peer dependencies solve
NPM's module system is hierarchical. One big advantage for simpler scenarios is that when you install an npm package, that package brings its own dependencies with it so it will work out of the box.
But problems arise when:
Both your project and some module you are using depend on another module.
The three modules have to talk to each other.
In Example
Let's say you are building YourCoolProject and you're using both JacksModule 1.0 and JillsModule 2.0. And let's suppose that JacksModule also depends on JillsModule, but on a different version, say 1.0. As long as those 2 versions don't meet, there is no problem. The fact that JacksModule is using JillsModule below the surface is just an implementation detail. We are bundling JillsModule twice, but that's a small price to pay when we get stable software out of the box.
But now what if JacksModule exposes its dependency on JillsModule in some way. It accepts an instance of JillsClass for example... What happens when we create a new JillsClass using version 2.0 of the library and pass it along to jacksFunction? All hell will break loose! Simple things like jillsObject instanceof JillsClass will suddenly return false because jillsObject is actually an instance of another JillsClass, the 2.0 version.
How peer dependencies solve this
They tell npm
I need this package, but I need the version that is part of the
project, not some version private to my module.
When npm sees that your package is being installed into a project that does not have that dependency, or that has an incompatible version of it, it will warn the user during the installation process.
When should you use peer dependencies?
When you are building a library to be used by other projects, and
This library is using some other library, and
You expect/need the user to work with that other library as well
Common scenarios are plugins for larger frameworks. Think of things like Gulp, Grunt, Babel, Mocha, etc. If you write a Gulp plugin, you want that plugin to work with the same Gulp that the user's project is using, not with your own private version of Gulp.
I would recommend you to read the article again first. It's a bit confusing but the example with winston-mail shows you the answer why:
For example, let's pretend that winston-mail#0.2.3 specified "winston": "0.5.x" in its "dependencies" object because that's the latest version it was tested against. As an app developer, you want the latest and greatest stuff, so you look up the latest versions of winston and of winston-mail and put them in your package.json as
{
"dependencies": {
"winston": "0.6.2",
"winston-mail": "0.2.3"
}
}
But now, running npm install results in the unexpected dependency graph of
├── winston#0.6.2
└─┬ winston-mail#0.2.3
└── winston#0.5.11
In this case, it is possible to have multiple versions of a package which would cause some issues. Peer dependencies allow npm developers to make sure that the user has the specific module (in the root folder). But you're correct with the point that describing one specific version of a package would lead to issues with other packages using other versions. This issue has to do with npm developers, as the articles states
One piece of advice: peer dependency requirements, unlike those for regular dependencies, should be lenient. You should not lock your peer dependencies down to specific patch versions.
Therefore developers should follow semver for defining peerDependencies. You should open an issue for the grunt-steroids package on GitHub...
peerDependencies explained with the simplest example possible:
{
"name": "myPackage",
"dependencies": {
"foo": "^4.0.0",
"react": "^15.0.0"
}
}
{
"name": "foo"
"peerDependencies": {
"react": "^16.0.0"
}
}
running npm install in myPackage will throw an error because it is trying to install React version ^15.0.0 AND foo which is only compatible with React ^16.0.0.
peerDependencies are NOT installed.

Resources