初めてのnpm パッケージ公開

  • 117
    いいね
  • 0
    コメント

履歴

@qsona さんの編集リクエストより記載ミスを修正
@diescake さんの編集リクエストよりコマンドのtypo を修正
ありがとうございます :grin:

NodeJS パッケージの作成にあたって

NodeJS のパッケージを作成してnpm に登録するときに、実際に行った手順について備忘録として残しておきます。

  • 実施環境
    OS Ubuntu 16.04 LTS
    NodeJS 6.0.0
    npm 2.15.0
    作成したパッケージ(Git Hub リポジトリ名及びnpm パッケージ名) rpncc

今回はrpncc という、配列で渡された計算式を逆ポーランド記法に変換/計算したり、逆ポーランド方式の式を通常の式に戻すパッケージを作成しました。
最終的に完成したものは以下のものになります。

npm ユーザの作成

npm のauthor 情報及びユーザがまだ作成されていない場合は、npm set, npm adduser コマンドを使ってそれらを登録していきます。

author情報を作成する
$ npm set init.author.name "Tsutomu Nakamura"
$ npm set init.author.email "tsutomu-nakamura@example.com"
$ npm set init.author.url "http://qiita.com/TsutomuNakamura"

上記コマンドを実行すると~/.npmrc ファイルが作成されその中に入力した情報が格納されます。
次にnpm adduser コマンドを使ってユーザを登録します。

npmユーザの登録
$ npm adduser
## まだユーザが登録されていない場合は、npm に登録する新規ユーザ情報を入力する。
## 既にnpm ユーザが作成されている場合はそのユーザの情報を入れて、ログインする。

Git Hub リポジトリの作成

Git Hub で新規リポジトリを作成します。
今回は逆ポーランド記法(Reverse Polish notation)の計算や変換(calculate/convert)をしてくれるパッケージなのでrpncc という名前にしておきました。
そのため、rpncc という名前のリポジトリを事前に作成しておきます(作成手順は割愛します)。

リポジトリを作成したら、自分のローカル環境にclone しておきます。

clone
$ git clone git@github.com:TsutomuNakamura/rpncc.git
$ cd rpncc

npm init でパッケージの情報を入力

npm init コマンドを実行し、package.json ファイルを作成します。
package.json ファイルはこのパッケージが他のどのパッケージと依存関係にあるのかといった情報や、build に関する環境情報を記載して他の開発者や他ワークステーションとの間でbuild 環境を共有する手助けをしてくれます。

npminit
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (rpncc)                                                       # <- このパッケージの名前。カッコ内はデフォルト
version: (1.0.0)                                                    # <- バージョン
description: Reverse Polish Notation calculator/converter for js    # <- このパッケージの説明
entry point: (index.js)                                             # <- 何も入力せずEnter (default: index.js)
test command: ava -v                                                # <- テストコマンド。今回はava
git repository: (https://github.com/TsutomuNakamura/rpncc.git)      # <- 何も入力せずEnter (default)
keywords: rpm reverse polish notation rpncc                         # <- keyword を入力。npm search された時の検索キーワード
license: (ISC) MIT                                                  # <- 今回は"MIT" と入力
About to write to /home/tsutomu/Work/gitwork/rpncc/package.json:

{
  "name": "rpncc",
  "version": "1.0.0",
  "description": "Reverse Polish Notation calculator/converter for js",
  "main": "index.js",
  "scripts": {
    "test": "ava -v"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/TsutomuNakamura/rpncc.git"
  },
  "keywords": [
    "rpm",
    "reverse",
    "polish",
    "notation",
    "rpncc"
  ],
  "author": "Tsutomu Nakamura <tsutomu-nakamura@example.com> (http://qiita.com/TsutomuNakamura)",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/TsutomuNakamura/rpncc/issues"
  },
  "homepage": "https://github.com/TsutomuNakamura/rpncc#readme"
}


Is this ok? (yes) 

以上で初期状態のpackage.json の作成は完了です。

検証やテスト時に依存するパッケージの定義(package.json のdevDependency にパッケージの追記)

検証やテスト時に依存するパッケージをインストールし、package.jsondevDependencyに追記していきます。

具体的に検証、テスト時に依存するパッケージとはテスト自動化や自分の作成したパッケージ本体に依存するパッケージのことを指します。
これらのパッケージをnpm install --save-dev <package name></doe> コマンドを使って、インストールと同時にpackage.json` ファイルに定義を追加します。

node--save-dev
$ ava --init                       # npm install --save-dev でも良いがava の場合、ava init でもdevDependency に追記される
$ npm install --save-dev sinon     # 例えばテスト自動化に必要な依存パッケージとしてsinon が必要な場合は--save-dev でインストールする
$ npm install --save-dev rewire    # テスト時に使用するパッケージ
$ npm install --save-dev chance    # プログラム本体に必要なパッケージ
$ cat package.json
  ......
  "devDependencies": {
    "ava": "^0.14.0",
    "chance": "^1.0.2",
    "rewire": "^2.5.1",
    "sinon": "^1.17.4"
  }
  ......

また、パッケージインストール時に作成されるnode_modules ディレクトリはコミットする必要が無いので、.gitignore に記載しておくようにしてください。

補足: 検証、テスト時に依存するパッケージを削除する(package.json のdevDependency のパッケージの削除)

あとでパッケージが不要になった時に、package.jsondevDependency からパッケージを削除するには、npm rm --save-dev <package name> を実行します。

npmrm--save-dev
$ npm rm --save-dev sinon

本番時に依存するパッケージの定義(package.json のdependency にパッケージの追記)

本番時に依存するパッケージをpackage.json に追記します。
本番時に依存するパッケージはnpm install --save <package name> を実行すればOK です。

npminstall
$ npm install --save chance

上記コマンドを実行することでpackage.jsondependencies にパッケージ名が追記されます。

npminstall時のpackage.json
  ......
  "dependencies": {
    "chance": "^1.0.2"
  }
  ......

プログラムの作成

では次に、以下のようなファイル構成でプログラムを作成していきます。

rpncc/
  +-- index.js
  +-- package.json
  +-- test/
    +-- test-index.js

今回はテスト自動化のava の--watch モードを使用し、ファイルの変更が発生するタイミングで随時テスト行われるようにしながら開発を行っていきたいと思います。

テストの実行
$ npm test -- --watch
......
## ファイルに変更が発生したのをトリガーにテストが自動的に実行される

テストコードは以下のような形式で作成していきます…。

test/test-index.js
import test from 'ava';
import Rpncc from '../index';
import './lib/load_prototypes';

const rpn = new Rpncc();

test('rpn#convert should return "1 2 +" if the value "1 + 2" is passed', t => {
    t.true(rpn.convert(["1", "+", "2"]).equals(["1", "2", "+"]));
});

test('rpn#convert should return "1 2 -" if the value "1 - 2" is passed', t => {
    t.true(rpn.convert(["1", "-", "2"]).equals(["1", "2", "-"]));
});
......

パッケージ本体は以下のように作成していきます…。

index.js
......
function Rpncc() {
    ......
    this.convert = function(expression) {
        var priority;
        var argument;
        var stack = [], result = [];

        ......

        return result.concat(stack.reverse());
    };
}
module.exports = Rpncc;
テスト実行の様子
$ npm test -- --watch
......
  ✔ index › rpn#convert should return "1 2 +" if the value "1 + 2" is passed
  ✔ index › rpn#convert should return "1 2 -" if the value "1 - 2" is passed

Git Hub のトップページに、テストに合格した証のTravis CI バッチを貼り付けてる(任意)

テストに成功したことを表すTravis CI のバッチをあなたのGit Hub リポジトリのトップページに貼り付けてみましょう。
Travis CI のサイトにアクセスし、あなたのGit Hub アカウントでログインします。

ログインしたら、メニューの+ ボタンをクリックします。

CreateNPMModule_0000.png

repositories の"+" の部分をクリックすると、あなたのGit Hub のリポジトリが一覧表示されるので、テストを実行したいリポジトリを選択します。
今回はrpncc を選択します。
CreateNPMModule_0001.png

リポジトリを選択したら歯車のマークをクリックし、どのタイミングでテストを実行させるかを指定します。
今回はpush, pull requestが発生した時且つ.travis.yml ファイルがあった時のみ実行するようにしておきます。
CreateNPMModule_0002.png

上記の設定を行うことで、リポジトリに対してpush やpull request 操作が行われたタイミングでtravis 側のサーバで自動的にnpm install を実行して依存関係パッケージをインストールし、npm test でテストを実行し、結果を報告してくれるようになります。
それでは早速.travis.yml を作成し、git pushしてみましょう。

.travis.yml
language: node_js
node_js:
  - "6"
  - "5"
  - "4"
  - "4.4.3"
  - "0.12"

language:node_js と記載しnode_js: にサポートするnode のバージョンを列挙していきます。
このversion 番号はnode のバージョン管理パッケージnvm に送られて、指定したNodeJS のバージョンでテストが実行されるようになっています。

その他、NodeJS についての詳細なオプションについては以下のページが参考になります。
- Building a Node.js project
- https://docs.travis-ci.com/user/languages/javascript-with-nodejs

ファイルを作成したら、commitと push を行います。
今回は開発用branch をmaster にマージしてからpush しています。

gitpushorigin
$ git add .travis.yml
$ git commit -m "Added .travis.yml"
$ git checkout master                  # 開発用のブランチで作業していた場合はmaster ブランチへマージ
$ git merge some_branch                # 〃
$ git push origin master

push されると、以下のようにテストが開始されます。
CreateNPMModule_0003.png

テストが完了すると以下のようにテスト結果が表示されます。
CreateNPMModule_0004.png

テストに成功したら画面上のバッジをクリックし、バッジのURL を取得してください。
そのURL をGit Hub のREADME.md に貼り付けることでGit Hub リポジトリのトップにバッジが表示されるようになります。
CreateNPMModule_0004-02.png

gemnasium を使って依存関係パッケージ追跡のバッジを作成する(任意)

gemnasium を使用してプロジェクト内で使用されている依存パッケージの状態を追跡しましょう。
追跡することで、依存パッケージに新しいバージョンがリリースされたり、セキュリティ上の理由などによりアップデートが必要になった時に通知してくれるようになります。

こちらもGit Hub アカウントでログインし、対象リポジトリを登録していきます。
ADD NEW PROJECT からHOSTED ON GITHUB を選択します。

CreateNPMModule_0005.png

CreateNPMModule_0006.png

初めて作成する場合、次のように権限付与するように聞かれるので、今回はPUBLIC PROJECT を選択しておくことにします。

CreateNPMModule_0007.png

ADD PROJECTS FROM GITHUB 画面が表示されたら自分の名前の対象のリポジトリを選択し、SUBMIT ボタンをクリックします。
CreateNPMModule_0010.png

登録が完了すると依存関係のレポートが表示されますので、リポジトリ名の部分をクリックします。
CreateNPMModule_0011.png

リポジトリの設定ボタンを押下し、Badge タブを選択するとMARKDOWN 形式のサンプルが表示されるので、それをあなたのGit Hub リポジトリのREAMDE.md に貼り付けてください。

CreateNPMModule_0012.png

CreateNPMModule_0013.png

その他のバッジについて

その他、自作badge を載せたい場合はshields.io のサービスを利用すると簡単にできます。
手順は以下の記事がとても参考になりますので、ここでは詳細な説明は割愛させていただきます。

例えば追加でversion やライセンスのバッジをREADME.md に載せると以下のようになります。

CreateNPMModule_0014.png

ライセンスファイルの作成

あなたのパッケージにライセンスを明記しましょう。
今回、自分のパッケージはMIT ライセンスで公開するものとします。

Git Hub リポジトリのトップディレクトリにLICENSE.txt ファイルを追加し、ライセンス文を明記します。
記載内容は以下のページの文章の<year>, <copyright holders> の部分を自分の物に書き換えて使用すれば問題無いでしょう。

npm に公開

準備ができたら、自作パッケージを公開しましょう。
rpncc のGit Hub リポジトリにv1.0.0 のタグを作成し、それを公開します。

npmpublish
$ git tag -a v1.0.0 -m "My first version v1.0.0"
$ git push origin tags/v1.0.0
$ npm publish ./
+ rpncc@1.0.0

npm にパッケージが公開されました!
公開されたパッケージはすぐにnpm install コマンドでインストールできることが確認できます。

npminstall
$ npm install rpncc

patch バージョンのアップ

パッケージを使用していると後々bug が見つかってくる可能性があります。
bug fix によりパッチを当てたバージョンを公開する場合、ソースコードを修正した後にnpm version patch コマンドを実行してバージョンを上げ、再度npm publish で公開するようにします。

$ npm version patch              # <- v1.0.0 からv1.0.1 にアップ
v1.0.1
$ git tag                        # <- git のtag も自動的に作成される
v1.0.0
v1.0.1
$ git push origin tags/v1.0.1    # <- ただし、git push まではやってくれないので、必要に応じて自分でgit push ...
$ npm publish ./                 # <- npm で公開

マイナーバージョン、メジャーバージョンのアップについて(npm version minor, nom version major)

マイナーバージョン、メジャーバージョンをアップする場合はそれぞれnpm version minor, npm version major を使用します。

使用例
$ npm version minor    # v1.0.1 からv1.1.0 にアップ
v1.1.0

$ npm version major    # v1.0.1 からv2.0.0 にアップ
v2.0.0

その後はnpm version patch の時と同様に、必要に応じてgit pushnpm publish を実行してください。

latest, beta 版のtag 指定について

自分のプログラムの開発が進み、将来的にbeta 版パッケージとlatest パッケージの両方を公開したいと思う時があるかもしれません。
その場合にはnpm tag 機能を使用します。
この機能を使えば、例えば一般のエンドユーザには安定且つ比較的新しいパッケージをインストールさせ、一方で一部のエンドユーザには安定はしていないが最新のバージョン(beta版)を利用させるといった公開方針にすることができます。

今回使用したパッケージを例にv1.0.1latest として、v2.0.0beta として公開したい場合は次のようにコマンドを実行します。

npmdist-tag
$ npm dist-tag add rpncc@1.0.1 --tag=latest
$ npm dist-tag add rpncc@2.0.0 --tag=beta
$ npm dist-tag ls

上記のようにtag 付けを行った結果、エンドユーザ側は普通にnpm install コマンドを実行するとlatest なパッケージがインストールされ、beta タグを指定してnpm install した場合はbeta なパッケージがインストールされるようになります。

npminstallコマンドと、インストールされるバージョンの違いの例
$ npm install rpncc
    -> v1.0.1 がインストールされる
$ npm install rpncc@beta
    -> v2.0.0 がインストールされる
$ npm install rpncc@latest
    -> v1.0.1 がインストールされる

参考