yarn uses wrong version on workspaces - jestjs

I have a huge project, which I was will simplify for the issue, with 2 workspaces.
The main packages looks like
workspaces: [ 'workspace-A', 'workspace-B' ]
My workspace-A has a dependency to external package (here, jest), in a needed version
name: "workspace-A",
dependencies: {
"jest": "<27.0.0"
}
My workspace-B has a dependency to the same package, but doesn't care about its version.
name: "workspace-B"
dependencies: {
"jest": "*"
}
After a yarn install (with yarn v3), I was expecting yarn to automatically install jest with a 26.x.x version in my main node_modules.
Instead, the node_modules of the main project contains jest 26.x.x, and the node_modules of the workspace-B contains jest 27.x.x. It's OK for my, even if I find this weird, but the thing is the workspace-A now uses jest 27.x.x!
I succeeded make it work by adding a resolution field in the main package file, but it's not ideal, as this package doesn't need jest.
"resolutions": {
"jest": "^26.6.3",
}
My 2 questions are
Why is yarn installing 2 versions of jest, is there a way to prevent this?
Is there a configuration somewhere I should put to specify to the workspace-A to not use something from workspace-B?
Thanks for reading

Related

How to patch jest-rutime when using Yarn 2?

I am trying to follow the instructions in this repository to patch Jest.
Patch Jest.
It is suggested to use patch-package but I figured out that I can use yarn patch when using Yarn 2.
I managed to patch jest-runtime but seems Jest doesn’t seem to require jest-runtime in its package so I don’t know where it comes from to use it as a reference to declare the patched file.
Jest package.json
I understand if Jest was the one that needs to be patched I could declare it like this:
package.json
"devDependencies": {
"jest": "patch:jest#26.6.3#./patches/jest.patch"
}
I tried to use the same logic to include the following code to include jest-runtime but it didn't work.
"devDependencies": {
"jest": "^26.6.3",
"jest-runtime": "patch:jest-runtime#26.6.3#./patches/jest-runtime.patch"
}
How can I declare this patched jest-runtime so Jest can use it?
The Resolutions field in the manifest is the correct approach to declare the patched modules that we didn't add to devDependencies such as submodules.
The resolutions field allows you to instruct Yarn to use a specific resolution instead of anything the resolver would normally pick. This is useful to enforce all your packages to use a single version of a dependency, or backport a fix.
The fix for that issue:
{
...
"dependencies": {
"jest": "^26.6.3",
},
"resolutions": {
"jest-runtime": "patch:jest-runtime#26.6.3#./patches/jest-runtime.patch"
},
}

Google Cloud Functions error: "Cannot find module 'sharp'" but it's in my package.json

I am trying to deploy a function to Google Cloud Functions. I based it on their ImageMagick tutorial.
Every time, the function fails to deploy because it reaches an error. Looking at the log, the error is:
Provided module can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace:
Error: Cannot find module 'sharp'
I can't figure out why this is happening, because sharp is in my package.json dependencies. If I open the web editor for the function in the Google Cloud console, the package.json is there as one of the files and shows sharp as a dependency. I tried running npm install and npm install --save and re-deploying, and that hasn't fixed anything.
I'm including the package in the function with const sharp = require('sharp'); (this is the line where the log shows the error occurring), and this is my package.json:
{
"name": "Resize images",
"version": "0.0.1",
"private": true,
"author": "James Tyner",
"engines": {
"node": ">=10.0.0"
},
"dependencies": {
"#google-cloud/storage": "^5.0.0",
"sharp": "^0.25.4"
}
}
Can you help me figure out what I'm doing wrong?
This has happened to me many times since I was tricked to install packages in the project directory. It works fine locally but creates an error when you try to deploy.
It worked for me when I changed directory into the functions folder, instead of the firebase project folder and did a package install in there
cd functions
npm install [your missing package] --save
I was running into this issue. Various dependencies were causing my function deployment to fail. After a bit of digging I found that the peer-dependencies were not being included.
Adding this fixed my issue
"scripts": {
...
"gcp-build": "npm i npm-install-peers"
},
checking the docs.
the gcp-build command allows us to perform a custom build step during the function build process.
Somehow I was able to address the issue, but I don't fully understand what I did differently. I found that the dependencies listed in package.json weren't being installed when I ran npm install, so I created a separate folder and copied my code there, ran npm install in the new folder, and it worked well from there. Since then, the dependencies have been working properly when I change them and re-deploy the function.
Using Node v12.13.1 and serverless deployment with webpack to GCP and cloud-functions, I've struggled with this issue. In my case it was a different module though. The problem is that no module from node_modules will be possible to require or import. The reason becomes clear if one takes a look at the webpack zip-file in directory .serverless. It seems that with GCP nothing but the file (typically index.js) denoted as "main" in package.json is actually included.
The solution was to adapt webpack.config.js to explicitly include those files missing.
webpack.config.js

NPM conflicts with dependencies when installed locally using file path

I am developing two npm packages, say #ffx/alpha and #ffx/beta. Beta package is dependant on Alpha package.
alpha/package.json
{
"name": "#ffx/alpha",
"version": "1.0.0",
"dependencies": {},
"devDependencies": {
"some-package": "1.0.0"
}
}
beta/package.json
{
"name": "#ffx/alpha",
"version": "1.0.0",
"peerDependencies": {
"#ffx/alpha": "^1.0.0"
},
"devDependencies": {
"some-package": "1.0.0"
}
}
For local testing, I am building the Alpha project and install built code using following command inside the Beta project root,
npm install ../alpha/dist/#ffx/alpha
Also, I start building Alpha project in watch mode so that code changes in Alpha project reflect in Beta project (inside node_modules) immediately.
My issue is that, in some scenarios where I use the same dependancy in both Alpha and Beta project (some-package in above setup) Beta project get wrong reference of the same package and throw an error.
Example:
Say Alpha project has following code,
...
let smpkg = new SomePackage();
...
In Beta project, it will throw an error saying types missmatch.
error TS2322: Type 'import("~/alpha/node_modules/some-package").SomePackage' is not assignable to type 'import("~/beta/node_modules/some-package").SomePackage'.
Is there a way to align both references using this method?
Or is there a alternative way to use packages locally before publishing?
NOTE: I've already tried npm link and npm pack with mixed results.
I ran into a similar issue. This is how I managed to fix (I'll use your alpha/beta terminology):
Delete node_modules folders from both alpha and beta
Ensure any matching libraries in the package.json files for both alpha and beta match exactly. (For example, some-package should use 1.x.x instead ^1.x.x)
Run npm install on alpha
Ensure package.json for beta is pointed to local module (For example, #ffx/alpha: file:../alpha/dist/#ffx/alpha)
Run npm install on beta
This ended fixing everything for me.

How to fix broken Typescript definitions when definitions files are updated

I have a project that uses Typescript, using the newer #types/foo style of installing typings packages.
When my build server installs all npm modules, sometimes I get a complete failure when compiling the typescript as some dependent definitions are no longer matching up.
For instance, I now have a problem with #types/gulp. In its package.json, dependencies are listed as:
"dependencies": {
"#types/node": "*",
"#types/orchestrator": "*",
"#types/vinyl": "*"
},
But now #types/orchestrator has updated, and it now breaks the version of #types/gulp that I have defined in my apps package.json.
How am I supposed to lock down version of dependencies like this so I no longer get this problem, or is there another workaround?
Unfortunately, I suddenly get these issues which sets development back by hours trying to sort it out. This makes using Typescript in a fast moving environment difficult.
How am I supposed to lock down version of dependencies like this so I no longer get this problem
Run npm shrinkwrap or just specify an exact version:
"#types/vinyl": "6.3.12"

How to shim npm package dependency in browserify?

So I have a React project, in which I'm actually deploying with react-lite as the footprint is much smaller. I'd like to use react-nouislider, but in it's package.json, I've found this:
"peerDependencies": {
"react": "^0.14.0"
}
What this means is that whenever I require react-nouislider, it pulls in React instead of react-lite. How do I shim dependencies of an npm package from my top-level package.json?
This is how I'm shimming react-lite in:
"browser": {
"react": "react-lite"
}
And I tried this, but it didn't work:
"browserify-shim":{
"react-nouislider": {
"depends": "react-lite"
}
}
How is it possible to shim a dependency of a package itself?
Browserify Shim's tagline is:
Makes CommonJS incompatible files browserifyable.
Your issue here is that react-lite is already CommonJS compatible. For any CommonJS compatible file, Browserify will automatically add its dependencies and peerDependencies as appropriate, before Browserify Shim gets involved.
I suggest you change the peerDependencies entry in the react-nouislider package to the appropriate version of react-lite and remove your Browserify Shim config above as it's no longer needed. When you do this, be sure to run any tests in the react-nouislider package to make sure it still works with react-lite instead of React. A good way of doing this is forking react-nouislider to your own repo, making the change there, and pulling from that repo in your package.json.

Resources