Using devDependencies to override dependencies when running locally - npm

I have packages I want to run using a local version when running the code locally and published versions when running in production. Is there a way to do this with one package.json file using devDependencies? Something like the following, where the devDependencies will get used when running locally and the normal dependencies will get used when deployed to production:
"dependencies": {
"#me/pack1": "^1.0.1"
"#me/pack2": "^1.0.2"
},
"devDependencies": {
"#me/pack1": "file:path/to/pack1"
"#me/pack2": "file:path/to/pack2"
}
Currently, I am manually installing the local version after pulling a new branch, then reinstalling the deployed version before pushing my local changes. I am looking to remove this process if possible.

Related

different packages version sets based on environment in node

I need to install different packages version sets based on deployment environment in node app.
this must be the dependencies when the env = develop
"dependencies": {
"bootstrap": "^5.2.0",
}
and this must be the dependencies when the env = production
"dependencies": {
"bootstrap": "4.2.0",
}
Do you have some workaround for this?
You can use penv module. it allows to create environment file and you will be able to separate out dependencies based on environment.
https://www.npmjs.com/package/penv
There is another way to create multiple package json files. e.g. DEV.package.json, QA.package.json and main.package.json. you can merge them using npm module during your CI Process.
https://www.npmjs.com/package/package-json-merge

NPM uninstalls unrelated packages when updating another

I have a single package that I install updates for occasionally. All the other packages I'm fine with. However, upon installing a new package, NPM always removes exif-js and angularsortablejs packages from my library, therefore breaking my project which relies on those two. As a temporary fix, I thankfully have those stored in a node modules back up. I copy the folders back across to the project and it works fine.
Going forward, how do I update individual packages so that NPM doesn't feel the need to remove, what I believe to be, unrelated packages?
"dependencies": {
"angular-sortablejs": "^2.6.0",
},
Note, exif-js isn't listed in the dependencies, it's used be a script in the assets by using var _exifJs = require('exif-js');

How to determine the dependencies of older npm package versions

It appears to me that the dependency linkage on the npm site is only applicable to the current/latest version.
Is there some tidbit of information that I'm not aware of on how to determine what dependency version a package has other than by downloading it and inspecting the package.json file?
I feel like I'm wasting HOURS doing something I would expect to be much easier to do.
"It appears to me that the dependency linkage on the npm site is only applicable to the current/latest version."
Yes that's correct, www.npmjs.com will only show the dependencies for the latest version of a package.
Here are a couple of ways to discover what you want both programmatically and non-programmatically.
Programmatically:
Utilizing the npm view command with the following syntax;
npm view <pkg_name> versions --json
obtains a list of all versions available for a given package in the npm registry.
Note: The <pkg_name> part above should be substituted with the real package name.
For instance; running the following command for let's say the eslint package:
npm view eslint versions --json
prints the following to the console:
[
"0.0.4",
"0.0.5",
"0.0.6",
"0.0.7",
"0.1.0-dev",
"0.1.0",
"0.1.1",
"0.1.2",
...
]
Now we know what versions are available, let's say we want to list the dependencies for eslint version 0.1.2 we can run the following command:
npm show eslint#0.1.2 dependencies --json
This will print:
{
"optimist": "*",
"estraverse": "~1.3.0",
"esprima": "*",
"escope": "1.0.0"
}
Similarly, we can discover the devDependencies for eslint version 0.1.2 by running the following command instead:
npm show eslint#0.1.2 devDependencies --json
This will yield something like this:
{
"vows": "~0.7.0",
"sinon": "*",
"commonjs-everywhere": "~0.9.0",
"mocha": "~1.13.0",
"chai": "~1.8.1",
"grunt": "~0.4.1",
...
}
If you know that a package has a particular dependency in advance.
For instance; retrospectively after running the aforementioned command we now know that eslint version 0.1.2 has escope listed as a dependency.
So, if we wanted to know the version of escope that eslint version 0.1.2 needs, we can run the following command:
npm show eslint#0.1.2 dependencies.escope
^
Note: The package name follows the dot (.), i.e. .escope
This prints the following:
1.0.0
The non-programmatic way
I can't think of a reason why you would want to perform the following non-programmatic way instead of the aforementioned programmatic way when you have a CLI tool available to you. However, if you prefer manual tasks then here goes...
Note: YMMV using the following manual steps as it depends on how the package has been managed/maintained.
Typically, the source code of an npm package will be hosted on GitHub, so you can perform the following manual steps. This will avoid you having to download the package to inspect the package.json file.
For this we'll demonstrate for the eslint package:
Visit npmjs.com and type the name of the package in the "Search Packages" input field. We'll type eslint and hit the return key.
Next click eslint from the list of packages, which will take you to this page.
Click on the github link which typically appears on the right-hand side of the webpage and looks like this:
That will take you to the eslint repo, i.e. this one
On the Github page click the "Branch" button - which appears above the list of source code files, and looks like this:
In the pop-up panel that subsequently appears click the "Tags" button, then locate and click the version tag from the list that you want to discover it's dependencies. (Note: These tag names will typically correspond to the version released/published to npm)
This will then load the source code files in the browser for that particular release/version.
Locate the package.json file from the list of files and click it. This will load the contents of package.json in the browser, upon which you can read it and ascertain its dependencies.
Visualizing the dependency tree
I sometimes utilize this online tool https://npm.anvaka.com which can help you to visualize the complete dependency tree/graph for a given package - however it's for the latest version of a package only.
Here is the complete dependency tree/graph (many levels deep) for the latest version of eslint.

Cannot use t"_Schema" from another module or realm. Ensure that there is only one instance of "graphql" in the node_modules

I'm getting this graphql instance error. How should I fix it?
I've tried adding the following in package.json but it produce the same error.
"resolutions": {
"graphql": "0.13.0"
}
Cannot use t"_Schema" from another module or realm. Ensure that there is only one instance of "graphql" in the node_modules directory. If different versions of "graphql" are the dependencies of other relied on modules, use "resolutions" to ensure only one version installed.
Screenshot of error is attached here.

Enforcing shared dependencies in a monorepo

We have a monorepo using lerna and yarn workspaces. Multiple teams contribute packages to it and there are some common dependencies where we want to force people to use the same version.
What are the options to force all packages to use the same version of specific dependencies? Is there a way to achieve that without writing custom scripts?
I want to prevent this situation:
my-repo/
packages/
pkg-A/
package.json
"address-validator": 1.1.0
pkg-B/
package.json
"address-validator": 1.2.0
I know you can use lerna add or lerna run to add / upgrade in unison, but how to prevent an individual from unknowingly making their package unique?
I just noticed one nice solution to this problem in facebook's create-react-app. They import (all?) external dependencies in the react-dev-utils package and export them from there. Then all the other packages, like react-scripts, import dependencies from react-dev-utils.
This is nice because you only need to worry about using the latest version of one package (e.g. react-dev-utils) in order to use the latest version of all of the things you want to control. Also, it's flexible because you can override one of the dependencies by importing a different version directly.
So it could look like:
my-repo/
packages/
my-deps/
pkg1.js // <--- module.exports = require("pkg1");
package.json
"pkg1": 1.2.0
foo/
index.js // <--- const pkg1 = require("my-deps/pkg1")
package.json
"my-deps": 1.1.0