Should a peer dependency be added in both peerDependencies and dependencies in package.json? - npm

I have a library that uses npm packages that I want as peer dependencies where the app would have to install them (eg. axios, react, react-dom). The goal is to avoid having libraries add to overall bundle size of the app.
Should I add these only under "peerDependencies" or is it okay to add it to "dependencies" as well? I thought it would be good to remove them from "dependencies" just to be sure that they don't get installed on top of what the app already has. However, if I exclude them from "dependencies" then my library tests start to fail because they are only peer dependencies and npm didn't install them.
I thought of installing them manually or adding them as devDependencies just for the purpose of running tests, but I think there has to be a better way. If I add both "dependencies" and "peerDependencies" does npm actually ignore the same dependencies in peerDepenedencies?

Related

Making sure NPM dev dependencies match corresponding peer dependencies

I pretty much always end up adding my NPM modules peer dependencies to dev dependencies as well because I need the peer dependencies installed so I can run automated tests before building the package. This creates the problem that I might accidentally use different version number for peer and dev. I find it odd that npm and yarn do not install the peer dependencies automatically when I run npm install or the yarn command. In some cases I have found that yarn even tries to prevent me from adding the same dependency as both peer and dev dependency. I think I'm doing something wrong but I haven't been able to figure out the intended workflow. Can someone explain to me how this is supposed to work?

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.

differences of dependencies and devDependencies

I'm new to nodejs and npm, just a question on dependencies and devDependencies
When I create a new react or Angular project, then I added a new required package by
npm install xxx --save
so the command above add the new package entry to "dependencies" in package.json file.
then I run npm start. The project is working OK and it is using the package I just installed.
But when I run npm start, I'm still in development environment, isn't it? and if the entry is not added to devDependencies, how can the application still run in development? I'm confused
The difference between these two, is that devDependencies are modules which are only required during development, while dependencies are modules which are also required at runtime. So while development we use both of them. For more details check here.

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

dependencies and devDependencies when using webpack

Does it make sense to put any modules into package.json dependencies when I use webpack?
When I want to develope a package, I use git clone <url> then npm install, then npm installs all dependencies and devDependencies from package.json file and it makes sense.
When I'm end-user and I just want to install some package into my node_modules to use it in my project, I run npm install package-name, then npm installs package-name with only its dependencies, and it makes sense too.
But does it make sense to put any modules into dependencies when I use webpack? The webpack will bundle all dependencies into eg. bundle.js, so, for me, there is no need to install dependencies then (while they're included into bundle.js file).
Let's assume that I put all neccessary modules into devDependencies (keep the dependencies object empty) for my project: my-project, bundle it with webpack and publish:
the developer-user will use git clone <url to my_project>, then run npm install, then npm will install devDependencies from package.json (and ommit empty dependencies object), then it is ready to develope.
the end-user will use npm install my-project, then npm will install my-project, do not install devDependencies (because this is for production) and do not install dependencies (because dependencies object in package.json remain empty). Putting anything into dependencies would double the dependencies: both the dependencies would be installed, and the same dependencies would be accessible in the bundle.js file.
Am I right?
You are correct that there may be no dependencies once it's been transpiled with webpack. However, some packages are multi-purpose and may be used in multiple ways, so in some circumstances dependencies may still be required.
If you look at the package.json specification, there are two possible entry points, 'main' and 'browser'. There is also the proposed 'module' entry point. It is currently under discussion about how to handle these in webpack and users seem to want webpack to prioritize them as module > browser > main, however browser is currently used by webpack first.
The idea behind prioritizing them in the order module > browser > main is presumably that browsers could use the pre-transpiled stuff directly in "browser", whereas another project calling require() or include() on your package would use non-transpiled code from the "module" entry. The "module" entry code could contain modern JavaScript with new features and the project/package requiring it could then transpile it to their own specifications, using "browserslist" for example.
I found this question because I was wondering the same thing...