こんにちは、デザイナーの岩淵です。

いまさらながら自作jQueryプラグインのnpm公開手順を簡単に説明していきます。省く部分もありますがご了承ください。

記事を見るだけだと分かりづらいので、実際に一緒に学習していく形の記事になっています。だいぶ長い道のりですが一連の流れを覚えれば簡単に自作コードをnpmパッケージとして公開し管理できるようになります!






STEP.1 前準備

GithubでてきとうなPublicリポジトリを作成しておいてください。
リポジトリ名はなんでもかまいません。

Privateリポジトリはnpmの有料プランに登録していないと公開できないらしいので、無料で公開するためにPublicリポジトリにしましょう。

こちらにある STEP1-前準備フォルダの中身を、あなたが用意したリポジトリにすべてコピーしてください。

あとyarnコマンドをメインに使っていくので、インストールしてない方はしておきましょう。

npm install yarn -g



STEP.2 package.jsonとLICENSEファイルの準備

package.jsonを編集

↓今回さわるのはこちらの項目

name npmに公開するパッケージ名になります。他人のとかぶることはできません。早いもの勝ちです。
しかし今回は名前空間(スコープ)をつけて公開しますので、パッケージ名は自由です。
@ユーザー名/パッケージ名のようにつけます。名前空間を持たせない場合は@ユーザー名/はいらず、そのままパッケージ名を記載します。
@tanaka/my-pluginのように自分のユーザー名で記載してください。
version パッケージのバージョンになります。
npm公開後にパッケージを更新する際は、同じバージョンでは更新できないので変更してから公開しましょう。
ここはそのまま0.1.0で大丈夫です。
description パッケージの説明です。コマンドでnpm search 〇〇〇〇と実行すると当てはまるパッケージが一覧で出てきます。
今回はあとで検索しやすいように独特な単語をチョイスしてください。
keyword description同様、npm searchで見つけてもらうことができます。
jQuery依存のパッケージの場合はjquery-pluginを含めておくことがマストのようです。
こちらも独特な単語をいれてください。
license ライセンス形態を示します。後にMITのライセンスファイルを作成しますので、MITと入力しましょう。
main パッケージで最初に読み込まれるファイルを指定する項目です。
例えばdist/tanaka.min.jsと設定するとJavascriptでrequire('パッケージ名')import 'パッケージ名'した際に、パッケージのルートから相対パスでdist/tanaka.min.jsを読みにいきます。何も指定しなければindex.jsを読みます。
今回はそのままindex.jsでやりましょう。
private trueだとプライベートパッケージという扱いなので無料公開できません。そのままfalseにしておきます。
repository ソースコードが保管されている場所を示します。前準備でGithubリポジトリを準備したかと思うので、そのリポジトリのURLを貼り付けておきましょう。
npmに公開するとそこへのリンクが自動で貼り付けられます。
author パッケージの作者名になります。名前以外にもメールアドレスなども記載できます。authorは一人しか設定できないので、共同開発者がいる場合はcontributorsという項目で複数人設定することができます。

追加で指定したい項目がある方はこちらのサイトにpackage.jsonのさらに詳しい説明が掲載されています。npm本家の文書を日本語翻訳したものらしいです。



LICENSEファイルをGithubから作成

様々な種類のライセンス形態がありますが、今回はMITライセンスで作成します。

右クリックからテキストドキュメントとして作成してもいいですが、Githubから作成することもできるのでその方法でいきましょう。Githubのリポジトリへ移動してください。そして以下の手順をふみます。

  1. Create new fileを押します
  2. licenseと入力します
  3. 右にChoose a licesnse templateが出現するのでそれを押します
  4. 左からMIT Licenseを選びます
  5. 右のReview and submitを押します
  6. ページ下部からコミットメッセージを入力し、今回は直接masterで作業するのでCommit directly to the master branch.を選択し、Commit new fileを押します

これでライセンスファイルが作成されコミットが完了しました。後の作業をスムーズに行うためにpullしておきましょう。




STEP.3 jQueryのプラグインを作成する

プラグインの内容となるindex.jsを見てみる

作成するといいましたが、時間短縮のために簡単なものを用意しておきました。落としてきたSTEP1-前準備のなかにあるindex.jsが公開するプラグインの内容になります。

;(function ($) {

  $.fn.myplugin = function(config) {

    if(!config) {
      config = {};
    };

    const target = config.target || '.myplugin-target';
    const addClass = config.addClass || 'on';
    const fade = config.fade || false;

    this.on('click', function() {
      $(target).toggleClass(addClass);
      if(fade) {
        $(target).fadeToggle(1000);
      }
    });

    return this;

  }

})(jQuery);

すでにjQueryで色々と行う処理が作成されていますね。
testフォルダに動作確認用のファイルを作成してあります。

;(functionという始まり方をしていますが、これはjQueryのメソッドチェーンで$('body').plugin1().plugin2();などと同一のオブジェクトに複数のメソッドを適用する方法において、まれに;をつけ忘れているプラグインが存在するようで、そのようなプラグインの後にチェーンした際にエラーになってしまわないようにこのような記述になっています。

詳しいjQueryプラグインの作成方法は「jquery プラグイン 作成」などで調べてみてください。


動作を確認してみる

まずはインストールしましょう。

yarn install

動作確認の環境も準備してあるので、確認してみてください。

yarn start

test/index.htmlから動作を確認できます。2ずつのボタンとテキストが出てきますね。プラグインを適用したボタンを押すとターゲットとして設定したクラス名に対して、付けたいクラス名をtoggleClassするという内容です。右側はそれに加えてfadeToggleもかかるようになっています。




STEP.4 Jestでテストを作成する

テストフレームワークとしてFacebook産のJestを使用します。

npmに公開するからにはちゃんとテストに通っているものが望ましいです。テストされていないプラグインは導入を躊躇されますからね。

Jestをインストール

yarn add --dev jest

テストに使うファイルを用意

こちらにある STEP4-Jestでテストを作成するフォルダの中身をコピーしてください。

Jestのデフォルトでは*.test.jsまたは*.spec.jsをテストファイルと見なすので、index.test.jsという名前にしてあります。
他にも__test__という名前のフォルダ配下のjsすべてをテストファイルとみなすなどの特徴があります。
testMatchというオプションでこの設定を自由に変更することも可能です。


index.test.jsの中身を確認

簡単なテストがすでに書いてありますね。Jestの初歩的な機能しか利用していないので、公式ドキュメントも参照してみてください。

describe('テストグループ', () => {

  test('通常テスト', () => {

    expect('ここの値が').toBe('ここと一致していたらPASS');

  });

});

簡単な説明をしておくとJestはこのようにdescribeで複数のテストをグループ化し、testにテスト内容を指定するということができます。
様々なテスト方法が存在しますが、今回はマッチャーという方法でテストをします。マッチャーも様々な種類が存在するので、適切なものを選択する必要がありますね。

今回作成してあるものは、検証用のDOMを生成し、そのDOMに作成したjQueryを適用し、クリックイベントを強制発火させ、expect()内でターゲットのクラス名を取得し、toBe()の値と一致しているかという内容です。
用意したプラグインではクラスのつけ外しくらいしかしていないので、この方法が適切と言えるでしょう。


package.jsonにJestを設定

yarnコマンドからJestを実行するためにpackage.jsonのscriptsを以下のように記述してください。

"scripts": {
  "start": "node server.js",
  "test": "jest"
},

テストを実行してみる

yarn testで実行してみましょう。エラーで赤い文字がでてくると思います。エラー内容を見ると取得したクラス名がtoBeと一致していないことが分かりますね

「ExpectedとReceivedを比べてみたんだけど、is-activeなんてないぞ!不合格!」ということがパッと見でわかるよう親切なエラーメッセージを出力してくれています。

プラグインが正しく機能していればaddClassに設定したis-activeがついているはずなので、toBe('myplugin-target is-active')となります。toBeをそのように修正し、再度yarn testを実行してください。このようにPASSと表示されるようになるはずです。

しかし、このままではまだまだ中途半端なテストになりますので、もっと踏み込んでみましょう。


テストのカバレッジ(網羅率)を測定

カバレッジを測定することで、そのテストがどれだけの範囲をカバーできているかを知ることができます。
カバレッジが低いテスト内容だと、知らないところでエラーが起きている可能性があり信用度が低いので、今回はカバレッジをMAXまで持っていきます。

まずは先程設定したpackage.jsonの"test": "jest"の部分を

"test": "jest --coverage"

というように編集してください。
Jestにはcoverageを測る機能がついており、--coverageをつけるだけで測定結果を出力することができます。編集したらyarn testで結果を見てみましょう。

このような表が出力されますね。100が最高なのですがどれも半端な数値なので、カバーしきれいていないテストだと言えます。

↓各項目の意味はこちらです。

Stmts 各ステートメント(命令)がすべて実行されたか
Branch ifなどの分岐がすべて実行されたか
Funcs 各関数がすべて呼び出されたか
Lines 各実行可能行がすべて実行されたか
Uncovered Line カバーされていない行のピックアップ

さらにcoverageというフォルダが生成されていますので、その中にあるlcov-report/index.js.htmlを確認してください。

実行されていない箇所がハイライトされていますね。ホバーすると詳細まで教えてくれます。つまりその部分をカバーするようテストを調整すれば、カバレッジが100パーセントになるということです。


カバレッジがすべて100になるようテストを編集

はい、こちらも既に用意済みです。index.test.jsを開くと大量のコメントアウトがあったかと思います。
ひとつずつコメントアウトを外して実行結果を見ていきましょう。

まずはテスト内容②のtest関数部分をすべてコメント解除しましょう。
下記画像にある$(target).fadeToggle(1000);が実行されていない状態になっているので、そのルートを通るテストがテスト内容②に記載してあります。

このテストは用意していたfadeToggleのオプションも合わせて使用するという内容になります。テスト内容①に比べて、fade: trueというものが設定されていますね。
今回はクラス名ではなくstyleを取得しています。setTimeoutでfadeToggleが終わる1000ミリ秒間に設定しており、display: noneがついているかどうかという内容です。

ではyarn testを実行してみましょう。

カバレッジの数値が上昇しましたね。coverage/lcov-report/index.js.htmlを更新するとハイライトが1箇所消えたと思います。


残りの部分も解決しましょう。

テスト内容③をコメント解除してください。このテストでは配列に何も渡さない場合に初期値が適用されてくれるかをテストしています。
黄色いハイライト部分が配列に何も渡ってきていない場合に設定される値ですね。yarn testで結果を見てみましょう。

見事すべての項目が100になりましたね。ハイライトも全て消え、通っていない道がないテストが完成しました。


しかしながら、今回はとりあえず100に持っていったというレベル感のテストなので、より厳格で保守性の高いテストを目指す方はJest公式ドキュメントを参照しながら頑張ってください!




STEP.5 CIツールを使用する

CIとは継続的インテグレーションのことで、開発過程において頻繁にテストを行うことで問題を早期に発見し、品質の向上を図る開発手法のことです。
しかし、さきほどのJestを毎回手動で走らせて細かくチェックしていくのはとても手間ですよね。
そこで特定のタイミングで自動的にテストを実行し、テスト完了後にその結果を通知してくれるCIツールを利用するということです。

今回は2つのCIツールを利用し、Githubにプッシュした段階でさきほど作ったテストを実行し、結果を返してくれるよう設定していきます。

Travis CIにログイン

Travis CI

Githubアカウントでログインできます。

ログインしたらこのボタンからリポジトリの追加画面へ飛びます。

するとGithubで作成してあるリポジトリが一覧で表示されるので、適用したいリポジトリにチェックを入れます。リポジトリを取得するのに時間がかかることもあるので、出ない場合は気長に待ちましょう。

COVERALLSにログイン

COVERALLS

おなじくGithubアカウントでログインできます。

ログインしたらこのリンクからリポジトリの追加画面へ飛びます。

こちらもリポジトリが表示されますのでチェックしましょう。

以上でチェックしたリポジトリに対して2つのCIツールを使用する準備が整いました。


Travis CIとCOVERALLSを実行するためのファイルを作成

こちらにある STEP5-CIツールを使用するフォルダの中身をコピーしてください。

この.travis.ymlというファイルに実行の命令が記載されています。テスト自体はTravis CIのサーバー上で実行されます。

今回の内容はyarn installを実行し、yarn testを実行しテストし、テスト終了後にyarn add coverallsでCOVERALLSに送信するためのプラグインをインストールし、おまじないにより情報を送信する、という内容です。
テスト結果を指定のメールアドレスに送信なども出来ますので、細く設定したい方は.travis.ymlの書き方を検索してみてください。


Githubにpushし動作を確認

ここまで準備できましたらプッシュしてください。そしてブラウザからTravis CIの画面を開いておいてください、しばらくするとテストが実行されている様子を見ることができます。
Travis CIでテストが終わるとCOVERALLSに情報が送信されます。


生成されたタグをREADME.mdに貼り付ける

Travis CI

タグを押すとモーダルが出てきます。FORMATでMarkdownを選択し、RESULT部分をコピーして自分のREADME.mdに貼りましょう。

COVERALLS

リポジトリ名をクリックした先のページで、このような部分があります。矢印の指しているEMBEDボタンを押すと、MARKDOWNの項目があるのでこれもコピーしてREADME.mdに貼りましょう。

プッシュするたびにCIツールが動きますので、READMEを更新しなくてもタグが自動更新されます。それによってMarkdownのプレビューやGithubやnpmからいつでもテストの状態を簡単に確認できるようになります。
プラグインを利用したい人から見ても、このようなテストを通しているタグがあることは導入の基準になったりしますので、積極的に活用していきたいですね。

貼り付けたらプッシュしておきましょう。Githubでもタグの表示を確認できると思います。




STEP.6 npmに公開する

まずはnpmに登録

npmにアクセスしSign Upから登録してください。無料のプランがあるのでまずはそちらを選択しましょう。
確認用メールが送信されますので、URLを踏んでください。確認しないと公開できないようです。


いよいよ公開です。その前に.npmignoreを確認してください。こちらは.gitignoreと同じようにnpmに公開しないファイルを指定できるものです。プラグインの機能に関わらないものはすべて除外しても問題ありません。不要な画像などを上げてしまうと、ユーザーもそれを落としてしまいますので除外するのが親切ですね。
今回はある程度記載してあるのでそのままで大丈夫です。


これまでyarnを使用しておりややこしいかもしれませんが、yarnではなくnpmに公開する手順なのでここからnpmコマンドで覚えましょう。※npmをyarnにすれば同じようにnpmへ公開することもできます。

コマンドからnpmへ公開する

npm adduser

を実行してください。npmで登録した情報を入力しユーザーを追加します。パスワードを入力しても画面に変化がないように見えるかもしれませんが、ちゃんと打てていますので大丈夫です。


npm login

続いてこちらを実行してください。
ローカルからnpmにログインし証明書を記録させます。


npm config lsで登録した情報を確認することもできます。

ここまでできたらあとは公開です。
通常であれば、npm publishで公開できますが、今回は名前空間(スコープ)を持たせて公開するので

npm publish --access=public

といコマンドで公開しましょう。コマンドからならこの方法で名前空間で公開できますが、他にもpackage.jsonで指定する方法もあります。その場合は、

"publishConfig": { "access": "public" }

と追加すればnpm publishだけでも公開することができます。


npmに公開したパッケージを検索する

まずはnpmのサイトからパッケージ名で検索してみましょう。ヒットするはずです。
CIツールでつけたタグや、右にあるVersionやLicenseがpackage.jsonで記載した内容と一致していますね。

次はコマンドから検索してみましょう。

npm search 〇〇

で検索します。〇〇にpackage.jsonのdescriptionやkeywordの一部分を入力します。
すると該当するパッケージがリストで表示されますので、自分のパッケージ名を探してみてください。




STEP.7 読み込んで使ってみよう

npmへの公開が済んだのでいつでもインストールして使うことができます。
自分のテスト用プロジェクトなどでインストールし、このように書いて動作確認してみましょう。

import 'プラグイン名';

$('適用したい要素').myplugin({
  target: '対象の要素',
  addClass: '付けたいクラス名',
  fade: true
});

※importを使用しているのでそのままJavascriptに直書きしても、この記事の公開時点ではほとんどのブラウザで確認ができません。Webpackやbabelなどを利用して使える環境にしましょう。




STEP.8 学習用に公開したものなので削除する

最後にnpmから削除する方法を学びます。
npmは公開から24時間以内なら簡単に非公開にできます。それ以上をすぎると運営に連絡しなければ削除できないようです。

npm unpublish --force

このコマンドで削除されます。反映に時間がかかる場合もあります。
削除したらnpmで検索しても引っかからないことを確認しましょう。




おしまい

いかがでしたか?手順を踏んでみた方は無事に公開できたでしょうか。
よく使うコードをパッケージ化して管理し世界に共有するのは大事なことです。
我々が日々利用しているプラグインは誰かが公開してくれているから使うことができていますよね。
利用する側から利用してもらう側に立ってみると自分に足りない技術や多くの新しい考え方が見えてきます。

岩淵

岩淵 Webデザイナー

2017年にWebデザイナーとしてLYZONに入社。
現在はアートディレクターとしても活動中。