JamieMason / syncpack

Consistent dependency versions in large JavaScript Monorepos.
https://jamiemason.github.io/syncpack/
MIT License
1.41k stars 49 forks source link

question(config): how to pin local packages to "workspace:*"? #189

Closed kevinpruett-prime closed 9 months ago

kevinpruett-prime commented 9 months ago

If I have a structure like the following:

   └── apps
       ├── appA
       └── appB
   └── packages
       ├── pkgA
       └── pkgB

I want to make sure appA and appB always refer to the version of any packages/* with workspace:*

I've tried the following versionGroup:

  versionGroups: [
    {
      label: "Ensure we always reference the latest workspace version of our internal packages.",
      packages: ["**"],
      dependencies: ["@my-local-packages/**"],
      pinVersion: "workspace:*",
    },
  ],

But this just results in LocalPackageMismatch as it forces me to tag each packages/*'s package.json with a version: "workspace:*" declaration. But when these set, pnpm doesn't seem to work with these versions and always throws.

Is there an ideal setup for something like this?

kevinpruett-prime commented 9 months ago

It might be a pnpm issue. I wasn't successful with https://pnpm.io/package_json#dependenciesmetainjected but that's the closest I seem to get. Curious if anyone has run into this (fairly common) setup.

JamieMason commented 9 months ago

This should be totally possible, happy to help but could you create a minimal repro? There are a few things I need to know to be better able to help you.

Easiest way is to dupe your repo, delete everything but the package.json and syncpack config files, then anonymise anything you need to.

Thanks.

Erid commented 9 months ago

I'm getting the same problem; what essentially happens is that it works on first run, but that run updates every related local project's package.json's version to workspace:*, presumably to make the version match with the referenced version in the other projects.

I had to write a script to clean-up after every run of syncpack. I'll create a small project to replicate.

Erid commented 9 months ago

@JamieMason Here is a small sample repo: https://github.com/Erid/syncpack-test

If you run pnpm syncpack fix-mismatches, the versions of all the package.json become workspace:*. I'm unsure if this is a bug or if it's that I'm not configuring it properly.

I'd appreciate your help! If there's anything that I can help with, let me know.

Erid commented 9 months ago

I found the solution! In dependencyTypes I had to set it to ["dev", "prod"], I had local in the sample because I was trying that, but initially I had none set (so it defaulted to everything). Anyway, after reading the docs better, I realized local was doing it for version.

The initial problem I had is that it was working without any dependencyTypes, I just had to exclude local. Then in the sample I put local and found the same problem, so I forgot to remove it, but in reality I had it worst in the sample.

Anyway, I'm loving syncpack 🙂

JamieMason commented 9 months ago

You beat me to it @Erid, I was just writing a reply to you to say that 😆

Glad to hear it is sorted. I will leave this issue open until we learn how @kevinpruett-prime's project is configured.

kevinpruett-prime commented 9 months ago

Thanks for this conversation. Let me see if this relates to my "issues". I'll post back 🙏

kevinpruett-prime commented 9 months ago

Yeah, looks like @Erid 's solution worked for me:

I found the solution! In dependencyTypes I had to set it to ["dev", "prod"], I had local in the sample because I was trying that, but initially I had none set (so it defaulted to everything).

I'll mark this as closed. Thanks for the discussion 👍

JamieMason commented 9 months ago

Great, thanks to both of you 🥳

kevinpruett-prime commented 9 months ago

Actually, sorry to do this, but quick related question if you don't mind me reopening

When I run lint I do see the following error:

✘ name @prime/ui or version PACKAGE_JSON_HAS_NO_VERSION are not supported packages/ui/package.json > version [UnsupportedMismatch]

My semverGroup config is as follows:

  semverGroups: [
    {
      range: "",
      dependencies: ["**"],
      dependencyTypes: ["dev", "prod"],
      packages: ["**"],
    },
  ],

Does this suggest that, for example, I need to set @prime/ui's version attribute in package.json? Can I not leave it blank?

JamieMason commented 9 months ago

No problem. This was a recent bug, hopefully you are not on 12.1.0 and upgrading to that should fix it: https://github.com/JamieMason/syncpack/issues/183#issuecomment-1870188709.

kevinpruett-prime commented 9 months ago

I'm on 12.3.0

JamieMason commented 9 months ago

Something sounds wrong there so I'll take a look. In the meantime, the easiest fix for now is to just set a version of eg. "0.0.0"

kevinpruett-prime commented 9 months ago

Great, thanks @JamieMason 👍

imhoffd commented 9 months ago

I ran into this as well when following this example. I figured I could exclude dependencyTypes since I wanted them for both dev and prod and wasn't sure what was going on when it was setting my package.json versions to workspace:* (thus breaking pnpm install).

In my setup, I'm using workspace:* for all local packages in all environments (no packages in the monorepo are actually published). I ended up with this, which works great:

  versionGroups: [
    {
      label: 'use workspace protocol for local packages',
      dependencies: ['$LOCAL'],
      dependencyTypes: ['!local'],
      pinVersion: 'workspace:*',
    },
  ],

I'm new to syncpack and just wanted to thank @JamieMason and the contributors for building such a useful tool for monorepos! 🙌

JamieMason commented 9 months ago

Great @imhoffd, yes omitting dependencyTypes would use the default which is to include everything, what you've gone with there looks good 👍 thanks a lot for sharing.

JamieMason commented 9 months ago

Which version of syncpack are you both using @imhoffd and @kevinpruett-prime? It should be a fixed bug actually that a package's .version should be read only.

imhoffd commented 9 months ago

12.3.0

kevinpruett-prime commented 9 months ago

@JamieMason Yes, I'm on 12.3.0 as well.

These versionGroups property examples are working well, but still seeing an issue with semverGroups when I use the following:

  semverGroups: [
    {
      range: "",
      dependencies: ["**"],
      packages: ["**"],
    },
  ],

When I run syncpack lint, it prints the following: Semver Ranges = the version property of package.json files must always be exact ============== ✘ name @prime/ui or version PACKAGE_JSON_HAS_NO_VERSION are not supported packages/ui/package.json > version [UnsupportedMismatch]

Which does require these workspace dependencies to have their own version specified in the package.json.

This is fixed with a 0.0.0 version as you stated above. Happy to open a new issue with repro and close this out if that's helpful.

JamieMason commented 9 months ago

Thanks @kevinpruett-prime that new issue would be handy, it'll be easier for other users to discover too.