いわゆるバックポート対応(新しいバージョンに取り込んだものを古いものに適用)して公開したいというようなことがあると思います。npmでその対応をやってみたのでやり方。

やりたいこと


次のような感じです。

  • セマンティックバージョニングに従ってパッケージを公開している
  • 上位バージョン(例えば1.0.0)を先に公開している状態で後から(例えば0.1.0)を公開したい

先に結論


publishコマンドに--tag=<tag-name>を付与して公開すれば良さそうです。この時に<tag-name>latestやセマンティックバージョニング以外の値が良いと思われます。私は次のようにlegacyで公開しました。

1
$ npm publish --tag=legacy

参考になりそうなの


Easy Automatic npm Publishesというnpm公式のブログの中の「Branches and Dist-Tags」という項に次のような記述があります。

On the other side, I might want to land a bugfix or backport a feature for a legacy version. To do that, I create a git branch with the old version, and update package.json to add a legacy tag instead.

これによると--tag=<tag-name>を付与してpublishすればイケそうなのですが、実際にやってみている記事がどうやっても見つからりませんでした。個人プロジェクトのパッケージであれば正味失敗しても問題ないのですが、そうでないパッケージをリリースする必要があり、慎重を期す必要があったのでやってみました。

環境


テストした環境とか実際にpublishしたパッケージとかは下記のとおりです。

手順


現状確認

まず、現状を整理します。1.0.0がtaglatestで公開されています。

この状態で0.1.0を公開したいです。

下位バージョンを公開してみる

こういったケースでは、まずブランチを分けると思いますので、ブランチを切ります。その状態でpackage.jsonversionを変更します。

1
2
3
4
5
6
{
"name": "@yoshinorin/npm-publish-sandbox",
"version": "0.1.0",
"description": "Just test for publish npm package",
"main": "src/index.js",
...

そして、npm publishしてみます。予想ではここでリジェクトされるかと思っていたのですが、なんとあっさり公開できてしまいました。

1
2
3
4
5
6
7
8
9
10
$ npm publish

npm notice
npm notice package: @yoshinorin/npm-publish-sandbox@0.1.0
...
npm notice total files: 2
npm notice
This operation requires a one-time password.
Enter OTP: xxxxxx
+ @yoshinorin/npm-publish-sandbox@0.1.0

しかし、確認するとlatesttag0.1.0になっています。これではnpm installしたときにデフォルトで0.1.0がインストールされることになります。(たぶん)

tagを付与して公開する

次に先述の記事のとおり--tag=<tag-name>を付与して公開してみます。作業の都合上2.0.00.2.0が既に公開されているものとして、この状態で0.2.1を公開してみます。

package.jsonversionを変更します。

1
2
3
4
5
6
{
"name": "@yoshinorin/npm-publish-sandbox",
"version": "0.2.1",
"description": "Just test for publish npm package",
"main": "src/index.js",
...

なお、前述のとおり<tag-name>latestやセマンティックバージョニング以外の値が良いと思われます

1
2
3
4
5
6
7
8
9
10
$ npm publish --tag=legacy

npm notice
npm notice package: @yoshinorin/npm-publish-sandbox@0.2.1
...
npm notice total files: 2
npm notice
This operation requires a one-time password.
Enter OTP: xxxxxx
+ @yoshinorin/npm-publish-sandbox@0.2.1

公開後に確認すると、次のように2.0.0のtagがlatest0.2.1legacyと正しい形で公開されていました。

テスト


これらを公開した状態でnpm install @yoshinorin/npm-publish-sandboxを実行すると2.0.0のものがインストールされ、バージョンを指定すると0.2.1もインストールできます。めでたし。

余談


割と頻繁にあり得そうなケースだと思うのですが、なんでこんなに記事がないんでしょうか…