「3分でできるnpmモジュール」に、公開のための手順がまとめられていて分かりやすかったので(感謝)、実際に3時間でモジュールを作ってみました。そのときにやったことのメモ。
(ちなみに、作ったのはPhantomJSをgulpから使いやすくするプラグインgulp-phantomです。よかったら使ってください〜)
なにするの?
- モジュールのお膳立て
- 実装
- GitHubにソースコードを置く
- npmに公開する
1時間目
まずはお膳立てから。最低限、必要なファイルはこのあたりです。1時間目に、太字のファイルからやっつけます。
- package.json
- .npmignore
- .gitignore
- .travis.yml
- index.js
- test/
- LICENSE
- README.md
package.json
こんな感じのやつですね。公開しないプロジェクトだと、dependencies以外、省略しているケースもあると思いますが、npmに上げる場合は、一通り記載しておきます。
{
  "name": "gulp-phantom",
  "description": "phantomjs plugin for gulp",
  "version": "0.0.1",
  "homepage": "https://github.com/cognitom/gulp-phantom",
  "main": "./index.js",
  ...
}
モジュールのルートフォルダに移動して、
$ npm init
とやると色々質問されるので、それに答えていくと package.json が作られます。適当に答えておいて、後で直せばOK。
仕様はここにまとめられていますが、設定ファイルの例を見ながら説明してくれるインタラクティブ ガイドが分かりやすいです。
以下、重要なところだけメモ。他は類推でいけると思います。
- 
nameモジュール名 (アルファベットとハイフンが使えます)
- 
versionとりあえず 0.0.1 (npmに上げるときには都度変更)
- 
mainモジュールが最初に読みにいくファイル (index.jsとしました)
- 
dependencies依存モジュール
- 
devDependencies開発時のみ使うモジュール
- 
scriptsテスト用のスクリプトを指定 (後述)
- 
enginesnodeのバージョン指定
注・ハマりかけたところ
他のモジュールを参考にしようと思って、node_modulesにインストールされたものを見ると、 package.json にやたらいろいろ書いています。が、下記のものは手入力しなくてOKです。npmコマンドが勝手に補完してくれるので、気にせずスルーしましょう。
- readme
- readmeFilename
- bugs
- _id
- _from
.npmignore
必ずしも必要はありませんが、tmp/ディレクトリを外したいとかいった場合に指定します。
tmp
なお、
- .DS_Store
- .git
- npm-debug.log
- node_modules
あたりは、デフォルトで外されるので、いちいち書かなくてOKです。
.gitignore
npmの話というよりもgit一般の話ですが、.npignore に合わせてこちらも設定しておきます。
.DS_Store
npm-debug.log
node_modules
tmp
.travis.yml
Travis CIは、GitHubにプッシュすると自動的にテストをかけてくれるサービスです。.travis.ymlがその設定ファイルにあたります。テストを書くのは後半に回しますが、とりあえずこれだけ書きます。GitHubに上がっているリポジトリだと、ほぼ必ず  みたいのがついてますが、テストをパスしているとこれが緑(passing)になっていて、カッコイイ...もとい安心感があります。
language: node_js
node_js:
  - 0.10
2時間目
いよいよ、実装です。index.jsにガシガシ書いていきます。合わせて、テストをtestディレクトリに作っていきます。
- index.js
- test/
index.js
よくあるパターンは、こんな感じです。必要なモジュールをrequireして、module.exportsの中に実際のコードを書いていきます。実装についての詳細は、ここでは略。
var spawn = require('child_process').spawn,
    through = require('through2'),
    gutil = require('gulp-util'),
module.exports = function(options){
  ...
}
テスト・テスト・テスト
今回は、mochaを使いました。
testディレクトリの構成はこんな感じ。
- expect/
- test1.txt
- test2.txt
 
- fixtures/
- test1.js
- test2.js
 
- main.js (あるいは、main.coffee)
main.jsというか、main.coffeeにテストを書き書き。
should = require 'should'
phantom = require '../'
describe 'gulp-phantom', () ->
  describe 'phantom()', () ->
    it 'should pass file when it isNull()', (done) ->
      ...
    it 'should emit error when file isStream()', (done) ->
      ...
    it 'should trim newline at EOF', (done) ->
      ...
テストがだいたい書けたら、package.jsonにテストスクリプトを指定しておきます。
{
  "scripts": {
    "test": "mocha -R spec"
  }
}
ちなみに、テストをCoffeeScriptで書く場合は、--compilersと--requireの指定が必要です。
{
  "scripts": {
    "test": "mocha --compilers coffee:coffee-script --require coffee-script/register -R spec"
  }
}
これで、下記のコマンドでテストが実行できるようになります。Travis CIもこの設定を認識してくれます。
$ npm test
注・ハマりかけたところ
実は、この段階ではテストが通ったのですが、Travis CIで引っかかりました (泣)。mochaのタイムアウトだったので、describe のところでタイムアウト値を多めに設定して、事無きを得ました。
describe 'gulp-phantom', () ->
  describe 'phantom()', () ->
    @timeout 10000
3時間目
テストを含めて実装ができたら、READMEやLICENSEを用意して、GitHubに公開する準備をします。
- LICENSE
- README.md
この2ファイルを用意したら、
- GitHubに公開
- Travis CIを設定
- npmに公開
で、完成!
LICENSE
MITライセンスにしたので、こんな内容を入れておきます。全文はここにあるので、コピーしてきて、年と名前を差し替えればOK。
The MIT License (MIT)
Copyright (c) 2014 Tsutomu Kawamura
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, ...(略)
README.md
# gulp-phantom
A PhantomJS plugin for [gulp](https://github.com/wearefractal/gulp).
(略)
GitHubに公開
新しいリポジトリを作って、そこにソースコードをプッシュします。今回用意したのはこちら。
Travis CIを設定
アカウントを作っていない場合は、Travis CIにGitHubアカウントを使ってサインアップします。自動的に自分のリポジトリがリストアップされるので、該当するもののスイッチをONにします。作業としては本当にこれだけ。
TravisはGitHubにプッシュされたことをフックにして、自動実行されるので、README.md にビルドバッジ  を足してプッシュしてみます。
# gulp-phantom [](https://travis-ci.org/cognitom/gulp-phantom)
A PhantomJS plugin for [gulp](https://github.com/wearefractal/gulp).
(略)
しばらくすると、テストが始まります。「passing」になればOK!
npmに公開
ここからは、あと「3分」です。ぜひ、fnobiさんによる「3分でできるnpmモジュール」をどうぞ。
概略としては、サインアップして、
$ npm adduser
それから、モジュールのフォルダでnpm publishすればOK。
$ npm publish
あとは、別プロジェクトから、npm install <モジュール名>できるかチェックしておきましょう。
放課後
本筋から離れるものの、関連する話題をメモ。
npmで公開しないシャイなモジュール
いきなりnpmに公開するのは、ちょっと抵抗があったり、なかったり。npmでは、ローカルで開発中のモジュールも、ファイルパスを指定すればインストールできます。ただ、この方法だと--save-devできません。
$ npm install /path/to/dir
GitHub上に公開する必要がありますが、gitのURLを指定することもできます。この場合は--save-devが使えます。
$ npm install git://github.com/cognitom/gulp-phantom.git --save-dev
package.json に直接書く場合はこんな感じ。詳しくは、npm-installのドキュメントをどうぞ。
{
  "devDependencies": {
    "gulp": "*",
    "gulp-phantom": "git://github.com/cognitom/gulp-phantom.git"
  }
}