What is the yarn alternative of npm-shrinkwrap? - node.js

The npm-shrinkwrap ensures that installed packages also have the same version of dependencies that was used at the moment of publishing to the registry (These versions are stated in the npm-shrinkwrap which is then used on installation).
I am currently using yarn (and lerna for publishing) and working on a monorepo project with workspaces. Now I would like to have each package in the monorepo have same guarantees provided by npm-shrinkwrap.
One shortcoming of the npm-shrinkwrap is that it does not support workspaces. Hence I cannot use npm-shrinkwrap since it is only created at the root and does not influence how individual packages in the monorepo get installed.
Since I am using yarn, I was wondering if there is an alternative to npm-shrinkwrap in yarn?
Or maybe a better question is, using yarn/lerna, how do I lock version dependencies for publication, such that when my packages in the mono-repo are downloaded, they are downloaded with the exact versions of dependencies (and transitive dependencies) that was specified at the point of publication?

I found the following in the yarn docs (classic yarn 1.x)
If you are using an npm-shrinkwrap.json file right now, be aware that you may end up with a different set of dependencies. Yarn does not support npm shrinkwrap files as they don’t have enough information in them to power Yarn’s more deterministic algorithm. If you are using a shrinkwrap file it may be easier to convert everyone working on the project to use Yarn at the same time. Simply remove your existing npm-shrinkwrap.json file and check in the newly created yarn.lock file.
From here:
https://classic.yarnpkg.com/en/docs/migrating-from-npm

Related

Is there a way to tell NPM NOT to use globally installed packages during a build

We work in a large team on multiple projects and everyone has a different set of node packages installed globally.
This can cause different behaviour when different members of the team build a project.
Is there a setting in a package.json file (or other file) that we can apply that forces NPM to only use local packages that have been installed in the local project node_modules.
I assume that this is more relating to development tools and modules (netlify, standard, prettier, #babel/core, rollup, eslint, etc)
Using npm i --save-dev package-a package-b package-c to ensure that you have the exact and correct versions across your development teams. I would suggest looking at package.jsons in projects like three.js, react, nextjs etc to see how they handle it. It can be quite a task to get a correct baseline of devDependencies, but once set, it generally solves a lot of package dependency problems caused by global modules.
See this: http://npm.github.io/how-npm-works-docs/npm3/how-npm3-works.html

Can I switch React Native app from Yarn to NPM seamlessly or is it more involved?

I am now in charge of an app whose dependencies were installed using yarn. I am more familiar with NPM. Is switching over as easy as deleting the yarn.lock file and installing NPM to the project? The app hasn't been updated in a year or two so I'm trying to update everything.
Or maybe a better question is, can I install both NPM and yarn globally but pick and choose which one I use for what app? Will it cause issues if they are both installed globally on machine?
Thanks in advance
You can definitely have Yarn and NPM installed on the same machine without issue. NPM generally comes packaged with Node, so most people using Yarn will also have NPM installed, wether they use it or not.
In terms of switching a project from Yarn to NPM, it's a pretty straightforward process, like you described: remove yarn.lock and remove the existing node_modules directory just to avoid any issues.
The subtle issue here is that the yarn.lock will be the current source of truth for exactly which versions of each dependency (and sub-dependencies) is installed. So by removing the yarn.lock your package.json will now become the (incomplete) source of truth which will likely result in some dependencies being upgraded when you perform your first npm install -- then your package-lock.json will become the new strict source of truth.
Given you're planning on updating everything anyway, then this likely isn't going to be an issue, but it's worth keeping in mind as you're likely to see some minor dependency changes.

What does 'npm i --package-lock-only' do?

What does npm i --package-lock-only do exactly? The documentation is a tad shy on examples. https://docs.npmjs.com/cli/v6/configuring-npm/package-locks
I'm curious to know if I have older packages in my local node_modules folder and no package-lock.json file, will npm i --package-lock-only generate a package-lock.json according to the version in my local node_modules folder or will it generate a package-lock.json with newer package versions that is consistent with the semver ranges in the package.json that's published in the npm registry.
It will determine versions of packages to install using package.json, and then create a package-lock.json file with its resolved versions if none exists, or overwrite an existing one.
Significantly, it does not actually install anything, which is what distinguishes it from regular npm install (or the aliased npm i).
Well, #Ben Wheeler is acurate, but there's a place to give a little background on this process. In regular situation the package-lock is meant for set a complete dependency tree of every package and it's dependencies in your application, so every developer on a different machine will have the exact same tree. This is important because the dependencies packages might be updated with time and if every developer will use different versions it could break your application. So every time you do "npm i" if you do have a package.lock.json it actually install the packages from there and not from package.json.
Sometimes when developers have a dependencies errors they tend to delete the lock file and the node_modules. which is not always the best option. Most of the time it's enough to update only the lock file to reflect the package.json with the flag --package-lock-only, and then you can do again "npm i" to install your packages. The lock file should be committed to your project repo so everyone can use it to have the same packages version.
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
This file is intended to be committed into source repositories, and serves various purposes:
Describe a single representation of a dependency tree such that
teammates, deployments, and continuous integration are guaranteed to
install exactly the same dependencies.
Provide a facility for users to "time-travel" to previous states of
node_modules without having to commit the directory itself.
Facilitate greater visibility of tree changes through readable source
control diffs.
Optimize the installation process by allowing npm to skip repeated
metadata resolutions for previously-installed packages.
As of npm v7, lockfiles include enough information to gain a complete
picture of the package tree, reducing the need to read package.json
files, and allowing for significant performance improvements.

ReactNative: is it possible to avoid storing all dependencies in node_modules subfolder

I'm quite new to ReactNative so sorry if it's obvious, but..
Each RN project init-ed via CLI has a large number of node modules stored in project_root/node_modules. Not that I would mind, but if you have several projects it seems redundant and takes up time/space to move it to the source versioning system.
Wouldn't it be possible to retrieve all these same modules from the general node_modules on the machine instead ?
You never want to store dependencies nested in node_modules in your source control... it defeats the whole purpose of versioning and dependencies in general. Your package.json file will specify the versions so when you run npm install it knows exactly which dependencies to grab.
As an alternative, Yarn is an up and rising package client that Facebook developed that does a much better job of caching your packages locally so that way if multiple projects reuse the same depencencies, it will still satisfy the need to keep them in node_modules but doesn't need to perform http requests for each one.
Yarn doesn't replace NPM as a package registry, just a better client to download, maintain, and cache those packages.
Yarn also adds a yarn.lock file (similar to Ruby's Gemfile.lock) that allows you to lock in the specific versions used in your app, regardles of the package.json. This file can be stored in version control, which is probably what you were wanting to achieve by saving the node_modules in version control.
Some good reads...
Yarn vs NPM
Scotch.io Yarn Tutorial
Why I'm working on Yarn (Yehuda Katz)
I would echo Brad's answer: Don't put node_modules in version control. npm install will install the correct versions from the package.json. Just put package.json in version control, not node_modules.
However, if you still want to save disk space, you can install some of your dependencies in a general node_modules folder by using the link option:
npm config set link true -g
You can read more about link here: https://docs.npmjs.com/misc/config#link.
Note that you must not include node_modules in your version control when using this option since npm will put symlinks to the globally installed packages in node_modules. The global install location varies from machine to machine, so if node_modules is in version control, it may link to non-existent locations.

Can Yarn and npm be used by multiple developers on the same project?

I work in a team of about 20 other developers. All of our projects utilize npm packages and currently all of our developers are running npm to manage those packages. I'm very curious about Yarn and have it currently installed on my machine. However I'm nervous to actually use it to install packages in case it screws up a project for other developers.
My question is can one developer utilize Yarn on a project while other devs are using npm in the same repo? From what I've read, Yarn uses the same package.json file to get its dependencies. We ignore the node_modules in our repo, however we use npm shrinkwrap to lock dependencies. I know Yarn has a Yarn.lock file and that is where my concern lies. Has anyone attempted to run Yarn independently from their team and what issues have you run into?
Yarn doesn't read npm-shrinkwrap.json. It generates its own yarn.lock. While only you use yarn, the project in your environment might have dependencies version different then that your teammates have. However it's safe to try yarn in your own environment since it doesn't overwrite shrinkwrap file and won't impact other developers.

Resources