what is npm doing differently when loading a project with a github url vs the usual npm install? - npm

There's an npm module I'm using, that works fine in my project when installed with npm and its semver, but that fails with the below error when I try to install it with its github url.
The error: Uncaught Error: removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component'srendermethod, or you have multiple copies of React loaded
I'm loading the same version of the module, not changing any build configs, the only difference is loading with semver vs github url.
I should say, the module's lib folder is not checked into github. So I do run a build of the module manually.
I'm using webpack for the build. I suspect its a problem with the copies of react being loaded, but that doesn't seem to have changed, and webpack seems to be handling duplicates.
npm ls react:
├── react#15.6.1
├─┬ react-color#2.2.0
│ └─┬ reactcss#0.4.6
│ └── react#0.14.9
└─┬ react-with-context#1.2.1
└── react#15.6.1 deduped
A little confused, any tips appreciated
(If that makes any difference, the error seems to be thrown from a dependency of the module that I'm testing. And in both modules (the one I'm testing + its dependency), react is listed as a peerDependency package.json)

Related

React native monorepo with PNPM

My goal
I am trying to use React native monorepo with PNPM, because I need performance of pnpm.
Expected
I should be able to bundle React native app with pnpm android and start development server with pnpm start.
Actual results
I can bundle app, but I cant start metro server. I always get this error:
More info
I have node v16.14.2, react native v0.69.
I know default metro bundler doesn't support symlinks (https://github.com/pnpm/pnpm/issues/1252#issuecomment-667600769), which pnpm use, so I tried to patch metro in metro.config.js:
This works perfectly fine with pure React native repo like here e.g: https://github.com/gjhughes/react-native-pnpm-example
My project structure looks like this:
project
└───shared
└───backend
│ │ package.json
│
└───frontend
│ │ package.json
│
└───mobile-app
│ │ package.json
Here is my pnpm-workspace.yaml:
I am desperate. Is it even possible?
If you have any more questions, feel free to ask!
Use pnpm without symlinks. Create a .npmrc in the root of your monorepo with the following setting:
node-linker=hoisted
Remove node_modules and run pnpm install. Related docs: https://pnpm.io/npmrc#node-linker

How to use npm workspace

I develop my app by using npm workspace.but I am totally novice to this concept so that I would like to understand npm workspace behavior
.
├── package.json
└── packages
├── a
│ └── package.json
├── b
│ └── package.json
└── c
└── package.json
package.json
{
"workspaces": [
"packages/*"
]
}
My question is
①what happens when I run npm install in root directory ?
All the packages are installed in each repository ? or root directory ?
②npm install in each project is not recommended ?
if someone has opinion, will you please let me know.
Thanks
So long as all packages have the same version of dependencies listed (e.g. thing#1.0.0), then npm install run from the root of your repository will add the dependency into the root node_modules directory.
If one of your packages (e.g. packages/c) has a different version of a dependency (e.g. thing#1.0.1) then that would appear in packages/2/node_modules)
In theory you are using npm workspaces to ensure some consistency across packages, therefore ensuring your versions are consistent will mean node_modules is only ever created in the root of your repository

How do I find what npm package has a particular dependency?

My webpack project has a new error:
Browserslist: caniuse-lite is outdated. Please run next command npm update caniuse-lite browserslist
Which I haven't solved yet, but the underlying problem is: I don't have caniuse-lite in my package.json - so where is it?
btw: running that command makes no difference.
It's obviously a dependency or a dependency of a dependency, ad infinitum...
npmjs caniuse-lite lists 80 dependent packages.
Is there a way to search the dependency graph of packages to easily find what package in my package.json file is the parent that somewhere along the line depends on caniuse-lite?
You can easily check that by following way.
Checkout more here : https://docs.npmjs.com/cli/ls
npm ls contextify
app-name#0.0.1 /home/zorbash/some-project
└─┬ d3#3.3.6
└─┬ jsdom#0.5.7
└── contextify#0.1.15

webpack a module that contains node_modules

Question
I want to make changes to an open source JavaScript library. Using webpack and npm and keeping everything local, what options do I have to make changes to a local module and import it into project in place of an public npm module downloaded from the registry? The local module and consuming app will also be source controlled under two separate git repositories.
Problem
I am testing this within an Aurelia app, but I think it is a webpack and npm problem. I have an app called my-app which has a dependency on aurelia-binding. I wish to make local changes to aurelia-binding and push them to a fork in GitHub. My project structure looks like this:
└───my-app
├───.git
├───dist
├───node_modules
│ └───aurelia-binding
| ├───.git
│ ├───dist
│ └───src
└───src
When built and run, everything works as expected. To make a change to aurelia-binding and test them in my-app, I need to install its dependencies and build it. This results in a structure like this:
└───my-app
├───dist
├───node_modules
│ └───aurelia-binding
| ├───.git
│ ├───dist
| ├───node_modules
| | └───dependencies...
│ └───src
└───src
When the node_modules are installed on the dependency, webpack throws an error at runtime. The error may look like an issue with the aurlia module, but I do not believe this is the case.
Unhandled rejection Error: Error invoking SVGAnalyzer. Check the inner error for details.
------------------------------------------------
Inner Error:
Message: __WEBPACK_IMPORTED_MODULE_1_aurelia_pal__.a.createElement is not a function
I have also tried this using npm link with the library cloned next to my-app instead of within in but got the same result.
I used the following addition to the webpack.config.js to be able to use npm/yarn linked packages. It forces webpack to resolve the modules only using the main node_modules and not the "nearest" ones.
resolve: {
extensions: [".ts", ".js"],
symlinks: false,
modules: ["ClientApp", path.resolve('node_modules')],
}
Where "ClientApp" is the folder where my aurelia app is located. The symlinks parameter is used to prevent webpack from resolving the symlinked path to an absolute path.
A word of warning, with this setup you circumvent version checking by npm so you are responsible for linking a compatible version.

Share node_modules installation between sub-projects, while maintaining separate package.json files

I have the following folder structure:
project
├───components
│ ├───component-one
│ │ package.json
│ │
│ └───component-two
│ │ package.json
│ │
│ └───node_modules
├───node_modules
└───package.json
Project root project folder contains package.json and is intended to have various infrastructural modules installed (Gulp, for example, as the build is centralized).
Each component under components folder is eventually, after build and whatnot, is deployed somewhere to be consumed by an application - using the usual npm install from folder or tarball. For that reason, each component must maintain its own dependencies in its own package.json.
Going the trivial route, installing node_modules into each of the component folders would lead to a crazy amount of duplication, as there may be 100s of components, each installing mostly the same dependencies.
Ideally I would like to:
run, for example, npm install -D <module> in component-one folder
have package.json in that folder updated with the <module>
have <module> installed in the project folder
This can be achieved, to some extent, running (on Windows, in this case) mklink /D node_modules ..\..\node_modules from component-one to create a symlink.
However, symlinks are fragile and finicky, so I'd like to avoid that solution.
Is there an npm solution, via npm link or something that I am missing?