Different versions of React in an npm workspace - javascript

We would like to have a workspace with different versions of react in two npm packages of the same workspace, due to one of them having dependencies not yet compatible with v18. However we're not able to do this without one of the versions being hoisted up to the root level, causing issues for the app in the other package.
At least I think that's what's going on. A simple reproduction goes as follows:
Create a new npm workspace with two packages, packages/a and packages/b; the root package.json including workspaces: ["packages/*"]
Create a new app in each of the workspace packages using create-react-app
Degrade the version in workspace a down to 17 by editing its package.json
Add a hook in each app, which will error if there are two versions running
Remove all node_modules folders, delete all package-lock.json files, and run npm i in the root folder
Start the two apps. This gives the "several versions of react" error with the hooks. Examining the node_modules folder in the root level we see that it contains one of the react versions
We also tried running npm i in each of the packages separately with the same result
In addition we tried creating a similar setup but without the full app, only installing (different versions of) react and react-dom in the two; still the root level node_modules contains one of them.
Lastly we tried using --legacy-bundling, but we haven't been able to make it work; also we're not sure it's worth the cost.
Is there a way to have a workspace with two different versions of react?

Related

Must i specify dependencies in package json file

I just recently heard of the package.json file but all my small projects have always worked without it.
I've installed many npm modules globally and always use var x = require("express");"just for example" without even initializing the package.json and putting express as a dependency.
Is it really important
First of all, I strongly doubt require("express") will work out of the box without having the express package installed in your project's node_modules folder, but just globally. There are ways to accomplish this, though.
But even if you accomplished to require packages from the global installation folder, what happens if you have multiple packages requiring different versions of the same package? There may be breaking changes between major versions of packages. So if you install a new version of package xy globally, older projects of yours expecting a different version of package xy may stop working.
On just your local machine, you can achieve all that, still without a package.json though.
The main purpose of the package.json comes clear, when you want to share your project with other people. Aside from some basic information (like a package name and some description), it will also list the dependencies which need to be installed for the project to be runable. While the necessary dependencies may exist on your machine, how will you make sure, they are also installed on a different machine without having them listed somewhere? And the place for listing the dependencies of a package is -- surprise surprise --- the package.json file ...
They are global, not in your project so when you do the deploy, you will must have to install all global for each server.
Yuu can install packages-cli global, but project dependencies ( also dev on dev dependencies) is better have its own package.json so you can deploy.
Also if you share your project, how someone will know what packages is needed.
The better is to have for each project its own package.json on its root folder, even if you always use the same libs.

Why do we need multiple node modules folders inside each project?

I'm new to JS development and was wondering given that the size of node modules is an issue of concern where one has to even go on deleting the folder when many projects pile up and is not used, why can't we have a global node modules folder, like m2 for maven and then reference it in our projects?
Why do we need multiple node modules folders inside each project?
You can install packages globally and use them with the -g flag when using npm install.
But this isn't done often, and often isn't recommended, because the same package can have many, many different versions. SomeLibrary version 5.6.1 can be significantly different from SomeLibrary version 5.7.1. If you have multiple projects, they'll very often have different dependencies, and different dependency versions. If you try to source them all from the same global install, you'll usually run into problems very quickly. Having a separate node_modules folder for each project solves this problem for you; often, package versioning for each project you have will "just work" without any extra configuration.
There are also managers like Yarn which can cache package downloads, so you don't re-download huge numbers of duplicate megabytes over multiple projects
Variety of reasons. Just FYI, you can install npm packages globally using the -g flag when installing.
Here's some reasons:
Different project may require different versions of a package.
A single machine can consist of multiple different environment, i.e
containers or virtual machines.
Sharing code between projects/environments introduces potential security risks.
For the above reasons, and others, you might not actually want a projects
packages to leave the scope of that project.
since java script is not compiled, we will need to have all the plugins in each deployment verses maven is compiled so we can compile it to machine code with the plugin globally installed

Package doesn't relate on its internal node_modules packages dependencies, uses external scope instead

I can't figure out why project dependency babel-polifyll doesn't relate to its internal packages from the own node_modules root (they're present there actually). Instead, it trying to get some dependency packages from the same level as the common project node_modules scope...
I understand that this is not a bug in babel-polifyll, probably something happens in node/yarn environment for sure. Anyway, I can't spot what exactly wrong...
Error:
Babel-polifyll reqiure imports that links from external scope:
This is an NPM thing, it by default tries to install all packages at the root level, so dependencies can be shared between components. This way when you build your code, if you have three packages using same component, then you output file will only need to have one copy of the built sub-component in it. This keeps the file size down a lot.
NPM will put a dependancy as a child when two packages require different versions of a library and normally you would never notice when this happens, unless you go looking.
This is great when it works, which it does most of the time, but can be a bit of a pig to sort out when it goes wrong.
I just had a look and the latest version of core-js is v3.2.1, but babel-polyfil requires v2.6.5. So the quick fix might be to force install the older version.
npm i -D core-js#2.6.5
This might break something else, if that happens try doing
rm -rf node-modules package-lock.json
npm i
Hopefully that will the force what ever needs the newer version of core-is to install as a child dep and everything will then work for you.

Why one package's dependency impact another

I have a folder which name is project.
I use "yarn add" to install two packages (antd and antd-mobile),both of them have a dependency which name is rc-checkbox.
antd uses "rc-checkbox": "~2.1.5".
antd-mobile uses "rc-checkbox": "~2.0.0".
After running the command, project/node_modules has a 2.0.0 version rc-checkbox folder, and project/node_modules/antd/node_modules has a 2.1.5 rc-checkbox folder.
The weird thing is no matter which one I install first, antd-mobile's 2.0.0 rc-checkbox will be installed at project/node_module. And when I run the project, antd uses the rc-checkbox which version is 2.0.0 (it is supposed to use 2.1.5) and it causes the bug.
So why would this happen? I think two packages use same another package with difference version should not impact each other.
Copy from Here
Version locking
yarn generates yarn.lock after each installation which persists ALL versions of installed packages (as you probably know package can has also dependencies and dependency can have also dependency) so it can build up infinite tree of dependencies which can lead to very bad conflicts. Let's imagine this scenario
- lodash^1
- super_module#0.0.1
- - lodash#1.0.0
- another_module#0.0.01
- - lodash#1.x.x
Imagine scenario when maintainer of another_module decides to bump lodash to breaking changes version 1.2.0 what can happen is that npm in old days could fetch 2 different instances of same library, and 2 different version which could lead to extremely weird behavior. Because as you don't have exact lock in your module (you accept any semver version ^1.x.x and ^2.x.x so that means both sub modules would satisfie your requirements but fetch different version. Yarn will lock your yarn.lock AT THE TIME OF AN ADDING new package to the project, that means when other developers on your project will checkout the project he will also have same yarn.lock and yarn will ultimately "mimic" the state of package how they were installed when you committed yarn.lock on other hands NPM just looks to the semver satisfaction and can fetch 2 different version for 2 developers (assuming that in time packages are upgrading)

Npm install global modules on different location node js

I am on a unix os, ubuntu, and I am experiencing a problem in installing global modules.
When I tried to look up where the node_modules folder is, I found out that npm installed some of my global modules in
/usr/lib/node_modules
and some of them are installed in
/usr/local/lib/node_modules
I have no problem before on using this global modules, until such time I tried installing a generator, that is when I first thought of looking into the directories because, after installing the generator, it says that I haven't installed the generator.
What is odd is that when I tried some of the modules, they work perfectly fine except for the other modules, saying it wasn't installed.
Is there a way to uninstall/remove/clean my computer from nodejs including its module and install it again so that it will just be using a single directory, so there won't be any confusion.
Why do you think npm installed this things in two diff. directories.
It looks to me like you have had 2 different versions of nodejs installed. Probably a packaged version and then a new release?
It works because your node folder is probably set to /usr/local/lib/node_modules
Node allways traverses the folder tree when looking for modules so if you do a require('imNotHere') it will look in:
/usr/local/lib/node_modules/imNotHere
/usr/local/node_modules/imNotHere
/usr/node_modules/imNotHere
/node_modules/imNotHere
before failing.
In your setup modules in /usr/lib/node_modules will still be caught by this

Categories