7
头图

foreword

Now we want to develop a project. We all know that in order to facilitate project management, we need to write a version number. What is the initial version number during development? Did 1.0.0 or 0.0.1 start?

If a version number is XYZ, when should X be incremented by 1, when should Y be incremented by 1, and when should Z be incremented by 1, does incrementing 1 follow decimal? For example, should the next version of 1.0.9 be 1.1.0?

We often see some project versions with suffixes, such as React's 18.0.0-rc.3 and Vue's 2.7.0-alpha.12 . What do these mean? Are these suffixes fixed fields or can they be customized?

SemVer specification

Actually, semantic versioning is not an innovative idea, even if we don't know it, we are doing something similar, but a clear specification will make the versioning logic more clearly communicated to other developers.

So Tom Preston-Werner, founder of Gravatars and co-founder of GitHub, established a specification for semantic version control, semantic version referred to as semver , so this specification is called the SemVer specification, the specification address For: https://semver.org/lang/zh-CN/

I will briefly explain the content of it, and it is easy for everyone to understand:

version number format

Standard version numbers must be in the format XYZ , where X, Y, and Z are non-negative integers, and leading zeros are prohibited. X is the major version number, Y is the minor version number, and Z is the revision number. The English counterparts are expressed as major, minor, patch , and each element must be incremented by a numerical value. For example: 1.9.1 -> 1.10.0 -> 1.11.0.

Software with major version number zero (0.yz) is in the initial stages of development and everything can be changed at any time.

The version number 1.0.0 is used to define the formation of the public API.

Increment logic for version numbers

The revision number Z (xyZ | x > 0) must be incremented when only backward compatible fixes have been made. Corrections here refer to internal modifications made for incorrect results.

The minor version number Y (xYz | x > 0) MUST be incremented as new backward compatible features appear. It must also be incremented when any public API functionality is marked as deprecated. It can also be incremented when a large number of new features or improvements are added to the internal program, which can include revision level changes. The revision number must be zeroed whenever the minor revision number is incremented.

The major version number X (Xyz | X > 0) must be incremented whenever any incompatible changes are added to the public API. This can include minor version number and revision level changes. The minor and revision numbers must be zeroed whenever the major version number is incremented.

A brief summary is:

  1. Upgrade the major version number when there are incompatible API changes
  2. When adding features in a backwards-compatible way, then upgrade the minor version number
  3. Upgrade revision numbers when backward compatible bug fixes are made

About the Advance Version

The preceding version number can be marked after the revision by adding a hyphen followed by a series of identifiers separated by periods. Identifiers must consist of ASCII alphanumerics and hyphens, and no spaces are allowed. Numeric identifiers are prohibited from leading zeros, for example: 1.0.0-alpha.6

An advance release has a lower priority than the associated standard release, e.g. 1.0.0-alpha < 1.0.0

Being marked with an advance version number indicates that this version is not stable and may not meet the expected compatibility requirements.

question answer

In fact, there is not much content in the specification. Back to the first question at the beginning:

Q: How do I perform version control during the initial development phase of 0.yz?
A: The easiest way to do this is to use 0.1.0 as your initial development version and increment the minor version number with each subsequent release.

Q: How to judge the timing of releasing version 1.0.0?
A: When your software is used in a production environment, it should have reached version 1.0.0. If you already have a stable API that users rely on, it will also be version 1.0.0. If you're worried about backward compatibility, it should be version 1.0.0.

alpha beta and rc

Now we know that the characters after - in the previous version are customized. We often see that some library versions will carry words such as alpha and beta. Taking Vue as an example, there are 3.0.0-alpha.13 3.0.0-rc.1 these 3.0.0-beta.1 ?

Generally speaking:

alpha means the internal beta version, mainly used for development and testing to find bugs, it is not recommended for users to download
beta means public beta, you can try some features in advance
rc is the abbreviation of Release Candidate (version candidate), which means that the function of this version will no longer be added. Like the final release version, it is a bit like the preview version, and then some minor bugs may be changed, and the official version will be reached.

Of course, the library can also use its own version logic, such as React, which also has a next version and an experimental version. The specific release logic is also written on the React official website: https://react.docschina.org/docs/release-channels.html

npm specify version range

We often see characters such as ~ ^ appearing before the version number in the package.json file, for example:

 {
   "dependencies": {
    "react": "^1.2.3
    "vue": "~1.2.3",
  }
}

I believe we all know a little about the role of these identifiers, such as:

^ represents the update of the minor version number, for example ^1.2.3 represents the later installed version >=1.2.3 <2.0.0
~ represents an update of the revision number, for example ~1.2.3 represents the later installed version >=1.2.3 <1.3.0

Of course, the specific logic will be more complicated, such as:

^ will only perform updates that do not change the leftmost non-zero digit, so:

  1. ^0.2.3 equivalent to >=1.2.3 <2.0.0
  2. ^0.0.3 equivalent to >=0.0.3 <0.0.4
  3. ^1.2.3-beta.2 equivalent to >=1.2.3-beta.2 <2.0.0 , of which 1.2.3-beta.4 is ok, but 1.2.4-beta.2

    ~ If the minor version number is specified, only the revision number will be updated, if not, the version number will be updated, so:

  4. ~1.2.3 equivalent to >=1.2.3 <1.3.0
  5. ~1.2 equivalent to >=1.2.0 <1.3.0 (equivalent to 1.2.x)
  6. ~1 equivalent to >=1.0.0 <2.0.0 (equivalent to 1.x)
  7. ~1.2.3-beta.2 equivalent to >=1.2.3-beta.2 <1.3.0 , of which 1.2.3-beta.4 is possible, but 1.2.4-beta.2 is not

Besides ^ and ~ , NPM provides more ways to represent range versions: https://docs.npmjs.com/cli/v8/configuring-npm/package-json #dependencies

Just a few examples:

 {
  "dependencies": {
    "foo": "1.0.0 - 2.9999.9999",
    "bar": ">=1.0.2 <2.1.2",
    "baz": ">1.0.2 <=2.3.4",
    "qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
    "lat": "latest",
  }
}

The latest represents the label, and by default npm uses the latest label to identify the current version of the package.

When we install the package, we can also refer to these specified versions to install:

 npm install foo@1.2.3
npm install foo@">=0.1.0 <0.2.0"
npm install foo@latest

npm version

NPM also provides the npm version command to update the version number. The specific syntax is as follows:

 npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]

其中最主要的就是majorminorpatch ,比如你当下的项目的package.jsonversion for 1.0.0 :

When you execute npm version major , the version will become 2.0.0
When you execute npm version minor , the version will become 1.1.0
When you execute npm version patch , the version will become 1.0.1

premajor , preminor , prepatch are also the same:

When you execute npm version premajor , the version will become 2.0.0-0
When you execute npm version premajor , the version will become 1.1.0-0
When you execute npm version prepatch , the version will become 1.0.1-0

And when you execute npm version prerelease , the version will also become 1.0.1-0

prepatch prerelaseprepatch是增加patch号,先行版本号置为0, prerelase If there is no previous version number, it is the same as prepatch. If there is, it will add 1 to the previous version number. For example, when your version number is 1.0.0-0 ,

When you execute npm version prepatch , the version will become 1.0.1-0
And when you execute npm version prerelease , the version will become 1.0.0-1

You can also add another -m parameter on this basis:

 npm version patch -m "Upgrade to %s for reasons"

Among them %s represents the new version number, npm will create a commit message, which is equivalent to npm modifying the version number and then executing a sentence on the file git commit -am "Upgrade to %s for reasons"

For more npm version commands, please refer to the official npm documentation https://docs.npmjs.com/cli/v8/commands/npm-version

series of articles

The full list of Xian Yu's answers to readers' questions: https://github.com/mqyqingfeng/Blog

If you like or have inspiration, welcome to star, which is also an encouragement to the author.


冴羽
9.3k 声望6.3k 粉丝

17 年开始写前端文章,至今 6 个系列,上百篇文章,全网千万阅读