rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

RFC: obey user specific dist-tag

Open gemwuu opened this issue 2 years ago • 14 comments

When running npm install pkg@latest-1, npm should provide a way to save latest-1 into package.json.

References

  • Related to issue #5052
  • Related to RRFC #547

gemwuu avatar Jun 29 '22 08:06 gemwuu

Personally speaking, saving a special dist-tag to package.json doesn't seem a good idea to me. "beta" or "beta-2" can be acceptable, but what if "latest"? It could point to any version of the package, and it's extremely unpredictable without lockfile.

MondoGao avatar Jun 29 '22 08:06 MondoGao

Personally speaking, saving a special dist-tag to package.json doesn't seem a good idea to me. "beta" or "beta-2" can be acceptable, but what if "latest"? It could point to any version of the package, and it's extremely unpredictable without lockfile.

Normally, installing a pkg simply using npm i pkg and saving the semantic version(say ^1.1.2) into package.json are safe, compatible and reasonable. The same behavior runs predictable when using npm i pkg@latest too.

But what if I want a latest tag in my package.json? For now, the only way is to manually change the ^1.1.2 to latest. Of course, latest may not be a proper and normal case, latest-x would be much better.

This RFC is to meet the requirement above. If I want a pkg@latest-x in my package.json, I can use npm i pkg@latest-x --save-tag to clarify my intention. If I want a semantic version of pkg@latest-x, then I shall use npm i pkg@latest-x

gemwuu avatar Jun 29 '22 09:06 gemwuu

It’s very true that saving any tag - not just latest - will open the user up to silent breaking changes, which is why saving anything but a semver range to package.json is a bad practice.

What is your use case where you need to depend on the tag, but can’t depend on a semver range based on what it resolves to?

ljharb avatar Jun 29 '22 14:06 ljharb

What is your use case where you need to depend on the tag, but can’t depend on a semver range based on what it resolves to?

Automated prereleases for PRs is my use case. We have a tool which publishes on PRs with a generated prerelease and a dist-tag to track it. So you can say "I want to depend on the work happening in this pr, even it if is changed". Today you need to manually edit the package.json, instead I would like my automated tooling to comment on the pr with "to test this, run npm i pkg@pr-tag --save-tag".

Additionally, I think there is very little difference between * and latest in that it allows a user to opt into possibly breaking changes, so I am not sure there is any new risk here.

wesleytodd avatar Jun 29 '22 22:06 wesleytodd

And to be clear, I do not think it is a best practice to do * or latest or any dist tag in a production app or library. But again, it is already possible and frowned upon so this opens new UX while not introducing new risk of misuse.

wesleytodd avatar Jun 29 '22 22:06 wesleytodd

@ljharb We know */latest is bad practice, but in same case, we trust the tag, like dev tag or stable tag. So let we have the choice to use --save-tag or not

killagu avatar Jul 04 '22 03:07 killagu

Why do you trust the tag? There's the same lack of guarantee as latest has.

ljharb avatar Jul 04 '22 05:07 ljharb

Because the tag is generate by myself or platform i trust.

killagu avatar Jul 04 '22 12:07 killagu

In the pre-release scenario,semver may not works well. If I have two dev branch, foo and bar, I'll release two version, 1.0.0-foo.alpha.0 and 1.0.0-bar.alpha.0. If ^1.0.0-foo.alpha.0 save to the package.json, 1.0.0-bar.alpha.0 will install. So in this case should save dust-tag to package.json.

It's just for the test case, at last should release the latest version and modify the package.json.

killagu avatar Jul 04 '22 15:07 killagu

Having multiple release channels on the same major, let alone minor and patch, seems like an untenable use of semver to me.

ljharb avatar Jul 04 '22 16:07 ljharb

The bug fix/new feature will release in a new version, but not know in dev stage. Do we have best practice for this scenario?

killagu avatar Jul 05 '22 02:07 killagu

I'm not sure what you mean. If you have a bugfix, it's a patch; if it's a new feature, it's a minor; and if you don't want people to get those freely, then bump the major so they don't.

ljharb avatar Jul 05 '22 05:07 ljharb

Let me try to get this straight. There are several popular npm packages that are not obey SEMVER rules, such as TypeScript (read more), Runing npm i typescript and saving the typescript@^4.7.4 won't always be safe for my project. The solution to this situation will be using patch versions, which npm doesn't support for now.

This RFC provides a best practice, if these prerequisites below are met, (take TypeScript for example):

  1. TypeScript add dist-tags for each incompatible minor or patch versions, like tag-47 for 4.7.xtag-48 for 4.8.x etc.
  2. npm provides a way to save tag if this is actually I want, like --save-tag.

The best practice of using TypeScript should be npm i typescript@tag-47 --save-tag, because only this way can I prevent my project from ci/cd failures when typescript team publishs 4.9.x and break some features I'm using.

FYI @ljharb @wesleytodd

gemwuu avatar Jul 05 '22 09:07 gemwuu

No, the best practice for TS (and react) is to use ~, not ^.

ljharb avatar Jul 05 '22 14:07 ljharb