履歴
@qsona さんの編集リクエストより記載ミスを修正
@diescake さんの編集リクエストよりコマンドのtypo を修正
ありがとうございます
注意: 現在はGemnasium はGitLab に統合されたため利用できないようです。代わりはhttps://libraries.io/ あたりになるでしょうか
NodeJS パッケージの作成にあたって
NodeJS のパッケージを作成してnpm に登録するときに、実際に行った手順について備忘録として残しておきます。
- 実施環境
OS | Ubuntu 16.04 LTS |
---|---|
NodeJS | 6.0.0 |
npm | 2.15.0 |
作成したパッケージ(GitHub リポジトリ名及びnpm パッケージ名) | rpncc |
今回はrpncc という、配列で渡された計算式を逆ポーランド記法に変換/計算したり、逆ポーランド方式の式を通常の式に戻すパッケージを作成しました。
最終的に完成したものは以下のものになります。
npm ユーザの作成
npm のauthor 情報及びユーザがまだ作成されていない場合は、npm set
, npm adduser
コマンドを使ってそれらを登録していきます。
$ 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 adduser
## まだユーザが登録されていない場合は、npm に登録する新規ユーザ情報を入力する。
## 既にnpm ユーザが作成されている場合はそのユーザの情報を入れて、ログインする。
GitHub リポジトリの作成
GitHub で新規リポジトリを作成します。
今回は逆ポーランド記法(Reverse Polish notation)の計算や変換(calculate/convert)をしてくれるパッケージなのでrpncc
という名前にしておきました。
そのため、rpncc
という名前のリポジトリを事前に作成しておきます(作成手順は割愛します)。
リポジトリを作成したら、自分のローカル環境にclone しておきます。
$ git clone git@github.com:TsutomuNakamura/rpncc.git
$ cd rpncc
npm init でパッケージの情報を入力
npm init
コマンドを実行し、package.json
ファイルを作成します。
package.json
ファイルはこのパッケージが他のどのパッケージと依存関係にあるのかといった情報や、build に関する環境情報を記載して他の開発者や他ワークステーションとの間でbuild 環境を共有する手助けをしてくれます。
$ 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.json
のdevDependency
に追記していきます。
具体的に検証、テスト時に依存するパッケージとはテスト自動化や自分の作成したパッケージ本体に依存するパッケージのことを指します。
これらのパッケージをnpm install --save-dev <package name></doe> コマンドを使って、インストールと同時に
package.json` ファイルに定義を追加します。
$ 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.json
のdevDependency
からパッケージを削除するには、npm rm --save-dev <package name>
を実行します。
$ npm rm --save-dev sinon
本番時に依存するパッケージの定義(package.json のdependency にパッケージの追記)
本番時に依存するパッケージをpackage.json
に追記します。
本番時に依存するパッケージはnpm install --save <package name>
を実行すればOK です。
$ npm install --save chance
上記コマンドを実行することでpackage.json
のdependencies
にパッケージ名が追記されます。
......
"dependencies": {
"chance": "^1.0.2"
}
......
プログラムの作成
では次に、以下のようなファイル構成でプログラムを作成していきます。
rpncc/
+-- index.js
+-- package.json
+-- test/
+-- test-index.js
今回はテスト自動化のava の--watch
モードを使用し、ファイルの変更が発生するタイミングで随時テスト行われるようにしながら開発を行っていきたいと思います。
$ npm test -- --watch
......
## ファイルに変更が発生したのをトリガーにテストが自動的に実行される
テストコードは以下のような形式で作成していきます…。
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", "-"]));
});
......
パッケージ本体は以下のように作成していきます…。
......
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
GitHub のトップページに、テストに合格した証のTravis CI バッチを貼り付けてる(任意)
テストに成功したことを表すTravis CI のバッチをあなたのGitHub リポジトリのトップページに貼り付けてみましょう。
Travis CI のサイトにアクセスし、あなたのGitHub アカウントでログインします。
- Travis CI
ログインしたら、メニューの+
ボタンをクリックします。
repositories の"+" の部分をクリックすると、あなたのGitHub のリポジトリが一覧表示されるので、テストを実行したいリポジトリを選択します。
今回はrpncc
を選択します。
リポジトリを選択したら歯車のマークをクリックし、どのタイミングでテストを実行させるかを指定します。
今回はpush
, pull request
が発生した時且つ.travis.yml
ファイルがあった時のみ実行するようにしておきます。
上記の設定を行うことで、リポジトリに対してpush やpull request 操作が行われたタイミングでtravis 側のサーバで自動的にnpm install
を実行して依存関係パッケージをインストールし、npm test
でテストを実行し、結果を報告してくれるようになります。
それでは早速.travis.yml
を作成し、git push
してみましょう。
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
ファイルを作成したら、commitと push を行います。
今回は開発用branch をmaster にマージしてからpush しています。
$ git add .travis.yml
$ git commit -m "Added .travis.yml"
$ git checkout master # 開発用のブランチで作業していた場合はmaster ブランチへマージ
$ git merge some_branch # 〃
$ git push origin master
テストに成功したら画面上のバッジをクリックし、バッジのURL を取得してください。
そのURL をGitHub のREADME.md に貼り付けることでGitHub リポジトリのトップにバッジが表示されるようになります。
gemnasium を使って依存関係パッケージ追跡のバッジを作成する(任意)
【注意: 現在はGitLab に統合されたため利用できないようです。代わりはhttps://libraries.io/ あたりになるでしょうか】
gemnasium を使用してプロジェクト内で使用されている依存パッケージの状態を追跡しましょう。
追跡することで、依存パッケージに新しいバージョンがリリースされたり、セキュリティ上の理由などによりアップデートが必要になった時に通知してくれるようになります。
- gemnasium
こちらもGitHub アカウントでログインし、対象リポジトリを登録していきます。
ADD NEW PROJECT
からHOSTED ON GITHUB
を選択します。
初めて作成する場合、次のように権限付与するように聞かれるので、今回はPUBLIC PROJECT
を選択しておくことにします。
ADD PROJECTS FROM GITHUB
画面が表示されたら自分の名前の対象のリポジトリを選択し、SUBMIT
ボタンをクリックします。
登録が完了すると依存関係のレポートが表示されますので、リポジトリ名の部分をクリックします。
リポジトリの設定ボタンを押下し、Badge
タブを選択するとMARKDOWN 形式のサンプルが表示されるので、それをあなたのGitHub リポジトリのREAMDE.md
に貼り付けてください。
その他のバッジについて
その他、自作badge を載せたい場合はshields.io のサービスを利用すると簡単にできます。
手順は以下の記事がとても参考になりますので、ここでは詳細な説明は割愛させていただきます。
- クラウドサービスを活用して README にバッジをペタペタ貼る
例えば追加でversion やライセンスのバッジをREADME.md
に載せると以下のようになります。
ライセンスファイルの作成
あなたのパッケージにライセンスを明記しましょう。
今回、自分のパッケージはMIT ライセンスで公開するものとします。
GitHub リポジトリのトップディレクトリにLICENSE.txt
ファイルを追加し、ライセンス文を明記します。
記載内容は以下のページの文章の<year>
, <copyright holders>
の部分を自分の物に書き換えて使用すれば問題無いでしょう。
- The MIT License (MIT) - Open Source Initiative
npm に公開
準備ができたら、自作パッケージを公開しましょう。
rpncc
のGitHub リポジトリにv1.0.0
のタグを作成し、それを公開します。
$ 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
コマンドでインストールできることが確認できます。
$ 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, npm 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 push
とnpm publish
を実行してください。
latest, beta 版のtag 指定について
自分のプログラムの開発が進み、将来的にbeta
版パッケージとlatest
パッケージの両方を公開したいと思う時があるかもしれません。
その場合にはnpm tag 機能を使用します。
この機能を使えば、例えば一般のエンドユーザには安定且つ比較的新しいパッケージをインストールさせ、一方で一部のエンドユーザには安定はしていないが最新のバージョン(beta版)を利用させるといった公開方針にすることができます。
今回使用したパッケージを例にv1.0.1
をlatest
として、v2.0.0
をbeta
として公開したい場合は次のようにコマンドを実行します。
$ 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
なパッケージがインストールされるようになります。
$ npm install rpncc
-> v1.0.1 がインストールされる
$ npm install rpncc@beta
-> v2.0.0 がインストールされる
$ npm install rpncc@latest
-> v1.0.1 がインストールされる
参考
-
Publishing npm packages
-
Getting Started with NPM (as a developer)
-
Travis CIを使ってみた GitHubのレポジトリにバッジを貼りたかったから
-
Gemnasiumを試してみる
-
npmのあまり知られてない機能 10選
-
Creating and Publishing a Node.js Module
-
package.json - Specifics of npm's package.json handling
-
What's the difference between dependencies, devDependencies and peerDependencies in npm package.json file?
-
How to compare arrays in JavaScript?
-
自作ソースコードに、MITライセンスを適用する3つのやり方