Do yarn workspaces work with npm, too? - npm

I checked out a repo which uses yarn instead of npm as build tool.
in the package.json, it defines workspaces to deal with multiple sub-projects:
{
"workspaces": [
"packages/*"
],
"dependencies": [],
"devDependencies": [
// long list
]
}
As a result, the root package.json does not contain any runtime dependency. Just the packages/*/package.json contain those.
To compile (and start in dev mode) I do:
yarn install
yarn start
I have found no documentation, that workspaces is also recognized and correctly used by npm.
Is there a way to make it work with npm, too?

Now that npm v7.0.0 is out, npm supports workspaces. You can manage multiple packages from within a singular top-level, root package. See more at https://github.blog/2020-10-13-presenting-v7-0-0-of-the-npm-cli/
Your workflows will not get npm v7.0.0 by default unless you install it using npm install -g npm#7.

Managing dependencies in a monorepo is not supported with npm. The Lerna package is used to manage JavaScript projects with cross dependencies. I believe Lerna uses Yarn under the hood, but with Yarn as your project's package manager, this feature is supported out of the box.
Here is a repo that might be helpful to see how Yarn and Lerna work together: https://github.com/Quramy/lerna-yarn-workspaces-example

npm has plans to implement workspaces somewhere along the v7, hopefully. They've written about it in their blog and there's an accepted proposal.

As of 2020-08-11 Workspaces are available in the v7 beta.
RFC 26 First phase of workspaces support is added. This changes
npm’s behavior when a root project’s package.json file contains a
workspaces field.
https://blog.npmjs.org/post/626173315965468672/npm-v7-series-beta-release-and-semver-major
You can view and download the beta here:
https://github.com/npm/cli/tags

NPM version 7 support workspace management. Now we can manage our workspace dependencies using npm workspace.
More on the workspace support can be found here official site here.
https://docs.npmjs.com/cli/v7/using-npm/workspaces
If you are looking for a simple example follow this link
https://github.com/pravanjan/npm-workspace-example/tree/master
Tested using node v16.6.1
npm 7.20.3

Related

how do i add yarn package to react native project installed with npm?

Note: Do guide me if something is missing.
So, I wanted to install a package from https://rnfirebase.io/auth/usage, but I have an npm project. The command on the website has only for yarn. I don't want to add yarn to project because (Is there any harm in using NPM and Yarn in the same project?) it states that it is not recommended.
So, then how do I install it with npm?
You have to use yarn, or you can look for a package that has the functions that you are looking for using npm
You can install it with npm just fine, don't worry. They are all package managers installing npm packages from the same repository. There is no difference in what you are installing or how they are installed. You can get different node_module structures, but for yarn you need config for that.
Yes its not recommended because it generates different lockfiles that will dictate different structures and versions in your node_modules folder. You want multiples devs to have the same "experience". However, lots of JS frameworks will come pre-configured with yarn, like React Native and you just end up having two lockfiles. One for npm and one for yarn. There is no harm in deleting the yarn file and keeping the package-lock. If you delete both, a new lockfile for the package manager you are using will be generated on npm i | yarn i | pnpm anyway.
To install it with npm just use npm i <PACKAGE_NAME> so npm i #react-native-firebase/app.
Here is the npm repo page for that package, https://www.npmjs.com/package/#react-native-firebase/app, notice the install command is npm! Only reason firebase devs only mention yarn is because they are hipsters ;)

How to link a globally installed node package to a project with yarn?

I have just started using yarn and I can't figure out how to link a globally installed package to a project. With npm I would just run npm link <package-name> but it doesn't work with yarn.
when I run yarn link <package-name> it gives this error:
yarn link v1.22.4
error No registered package found called "express".
info Visit https://yarnpkg.com/en/docs/cli/link for documentation about this command.
The link functionality is not really meant for linking global packages to a project. It is meant to link a package that you are working on to another project that you are working on. The fact, that the npm link command can be used to link globally installed packages to the current project is just an implementation detail of npm. From the yarn docs:
For the vast majority of packages it is considered a bad practice to have global dependencies because they are implicit. It is much better to add all of your dependencies locally so that they are explicit and anyone else using your project gets the same set of dependencies.
So you should just add the dependencies via yarn add <package-name>.

Is there any way to avoid symlinking in monorepo built with yarn workspaces and lerna?

Lets say there is a monorepo with package A and B.
Package A is dependent on B. Package B is also published in npm registry. So when installing dependencies it does not install the package B from npm registry instead it symlinks to the local package B as intended.
But is there any way to avoid this behvaiour and always resolve package from npm registry?
Currently, it seems it's not possible out-of-the-box. For example, nohoist option in yarn is for packages-dependencies which don't exist in the monorepo. For example, react-native and so on. For same-monorepo packages being consumed by their sibling packages, nohoist does not work, I tried setting it on root package.json and also on the package. It does not work.
Notice I said "out-of-the-box".
I came here looking for a solution because I want to migrate my custom ESLint plugins to my npm package monorepo which happens to consume them.
The challenge is, ESLint plugins are not ESM, they are CJS, and in TS/pure ESM monorepo, ESM and CJS don't play well together.
My CJS ESLint plugins would get hoisted and ESLint plugin would refuse to load them, completely breaking my VSCode linting.
I came up with an idea to avoid this hosting by keeping npm packages which should not be hosted with a different name, for example, B-temp, and then, on CI, during publishing, rename them last second before publishing to npm to B.
This way, during local yarn/npm i call, local monorepo package B-temp would not get recognised and therefore, not hoisted. The yarn would fetch B from the internet. I could keep b-temp in ESM (set "type": "module" in package.json) then use esbuild to transpile to esnext-spec CJS (no transpiling to ES5 etc), then publish those dist/*.cjs.js builds to npm — except before publishing, edit the package.json, remove the "ESM-ness" — "type": "module" and exports.

Lerna does not support dependencies at the top level?

I am in the process of switching my monorepo (back) from yarn (with workspaces) to lerna/npm, because yarn is too slow and unstable. However, I made an surprising discovery. With the following trivial package.json:
{
"devDependencies": { "lerna": "^2.11.0" },
"dependencies": { "typescript": "^2.9.1" }
}
and an empty lerna.json (in other words, no packages at all), then when I run
$ lerna bootstrap
it does not install anything at all in any top-level node_modules directory. And if for some reason I have a node_modules directory with no .bin subdirectory, then lerna bootstrap fails to create or populate the .bin subdirectory.
Is lerna not designed to actually specify top-level packages which are to be installed (along with their binaries in .bin)? I do notice that if I try lerna add on a lerna monorepo with no packages, it complains that "lerna WARN No packages found in scope where tslint can be added."
I could not find anything related to this in the documentation. With yarn/workspaces, I was using the ability to install global (top-level) versions of things like TypeScript for use in my build scripts while maintaining control over the version installed.
From the Lerna docs:
You can add the root as a managed location (in the packages array of lerna.json) - if that's something you need. This would cause lerna to link root's dependencies to your packages' directories, run postinstall script along with the others, etc.

How do devDependencies work when you yarn add <package>?

If you have a project that depends on packageA and you yarn add packageA but packageA has a devDependency on packageB to build, shouldn't that cause packageA to not work for you? Since packageA won't be able to build unless its devDependencies are installed too?
I guess my main question is if a pacakge has a devDependency on a built tool like babel, how does it get built and work when it gets yarn added by a project? Shouldn't build tools like webpack be a normal dependency?
No, they shouldn't, because the package that is yarn added is already built in an environment where the devDependencies are available. For example, when a package needs babel or webpack to build, then during the publishing a built bundle is created in a CI/CD pipeline that is valid es5 code and that is what you pull from npm. No build required after that.
GOOD MORNING :)
If you are having dependency problems on your dependencies of package.json, it is very simple to solve =]
What happens is that the dependency modules that the modules of your project need (dependencies) must be installed in the global npm as a package node (module), that is:
npm install -g youPackageName
If you have already installed a module in other projects or in the current project and want to turn it into a global package, you can use the command:
npm link youPackageName