Corredor

ウェブ、プログラミングの勉強メモ。

npm パッケージを作って公開してみた

npm パッケージを Fork して公開してみたいなーと思い、まずはまっさらな状態から npm パッケージを公開するまでの方法を調べた。

ざっくりとした流れは以下のとおり。

  1. npmjs にユーザ登録する
  2. npm adduser でログインする
  3. npm init でパッケージを作る
  4. エントリポイント (index.js) の作成
  5. CLI (bin/my-module) の作成
  6. .npmignore の作成
  7. npm publish で公開する

今回この手順で作ってみたサンプルパッケージは以下。

ついでにこのサンプルパッケージの実装は以下。

では、この手順を詳しく説明する。

1. npmjs にユーザ登録する

まずは npm パッケージを公開している公式のリポジトリである、npmjs でユーザ登録を行う。

「Sign up for npm」から

  • Name (任意の名前 : 表示用)
  • Public Email (メアド : このアドレスに登録確認メールが飛んでくる)
  • Username (スコープ・パッケージに使用されるユーザ名)
  • Password (パスワード)

を登録する。

「Username」は npm パッケージの作者として表示される他、「@angular/cli」などのように「@ユーザ名/パッケージ名」という「スコープ・パッケージ」を作る時の「@ユーザ名」部分にあたる。

スコープ・パッケージは、元々プライベートモジュールを有料で扱えるもので、パブリックなパッケージなら無料で使えるようになった。これまでの npm パッケージ名は早い者勝ちだったが、ユーザ名を付与することで名前空間の衝突を避けられるようになった。

登録するとメールアドレスに確認のメールが飛んで来るので、URL にアクセスしてユーザ登録完了。

2. npm adduser でログインする

続いてターミナルで $ npm adduser を実行する。ユーザ名とパスワードを聞かれるので入力すると、~/.npmrc にトークンが追記される。これで npm publish ができるようになる。

トークン情報はホームディレクトリの ~/.npmrc である必要はなく、npm パッケージと同じディレクトリに置いた .npmrc に書いておいても大丈夫な様子。ただしうっかりこのトークンを含んだ .npmrc を GitHub などに公開しないよう注意。

3. npm init でパッケージを作る

いよいよパッケージ作成。といっても、普段 npm パッケージを使うプロジェクトで行っているのと同じように、最初は npm init で始める。

今回はまず GitHub でパッケージ用のリポジトリを作り、それを git clone してきてから npm init する。こうすることで package.json にデフォルトで色々記載してもらえるので楽になる。

$ git clone https://github.com/【ユーザ名】/【リポジトリ名】
$ cd 【リポジトリ名】/
$ npm init

パッケージ名は @【ユーザ名】/【パッケージ名】 という書き方にするとスコープ・パッケージが作れる。npm init --scope=【ユーザ名】 と始めると自動補完してくれる。勿論後から package.json を手修正して @【ユーザ名】/【パッケージ名】 としても問題ない。

ちなみに、試してみたところ @neos21 というユーザ名と同じパッケージ名では npm publish することができなかった。スコープ・パッケージのユーザ名部分に付く @ は特殊な解釈を行っているようである。

エントリポイント (index.js) の作成

まずは package.jsonmain に記載される index.js を作る。これが、npm パッケージを require() した時に使えるモノとなる。

今回は、ただユーザ名と URL をコンソール出力するだけのファイルを作ってみた。

// index.js
function Neos21() {
  console.log('@neos21');
  console.log('http://neo.s21.xrea.com/');
}

module.exports = Neos21;

require() で使うために module.exports を忘れないこと。

CLI (bin/my-module) の作成

次に、グローバルインストールした時や npm run などで呼ぶ時に実行される、コマンドラインモジュールを作る。

bin/ ディレクトリを作り、コマンド名となるファイル名 neos21 を作ってみる。ユーザ名と URL を出力するだけのコマンドだ。

#!/usr/bin/env node

console.log('@neos21');
console.log('http://neo.s21.xrea.com/');

そしてこれをコマンドラインで呼び出せるようにするため、package.jsonbin プロパティを追加する。

"main": "index.js",
"bin": "bin/neos21",

.npmignore の作成

.npmignorenpm publish する際に後悔しないようにするファイルを設定するもの。.gitignore があって .npmignore がない場合は、.gitignore がそのままリネームされて .npmignore となって Publish されるようだ。

書き方は .gitignore と同じで、無視したいファイルやディレクトリを書けば良い。

4. npm publish で公開する

これでとりあえず完成。おもむろに $ npm publish --access=public を叩いてみると、あっという間に公開される。スコープパッケージの場合は --access=public オプションを付けないとプライベート扱いになるためオプション必須。

公開されたパッケージは以下のような URL で確認できる他、$ npm search 【パッケージ名】 で検索して表示されるようになる。

実際にパッケージを使ってみる

それでは実際にパッケージを使ってみる。

まずは適当なプロジェクトでローカルインストールし、index.js に作った関数を実行してみる。

# パッケージを利用する適当なプロジェクトを作る
$ mkdir test-project && cd $_
$ npm init -y

# パッケージをローカルインストールする
$ npm install @neos21/neos21 --save

# パッケージを呼び出して利用する JS ファイルを作ってみる
$ touch test.js

test.js ファイルには以下のように実装する。

// パッケージを読み込む
var neos21 = require('@neos21/neos21');

// 読み込んだパッケージの関数を実行する
neos21();

これで出来上がり。Node.js で test.js を実行してみると、正しくパッケージが読み込まれ、ユーザ名と URL が表示されるだろう。

# パッケージを利用しているスクリプトを実行する
$ node test.js
@neos21
http://neo.s21.xrea.com/

次に、グローバルインストールをしてコマンドラインモジュール (bin/neos21) を使ってみる。

# パッケージをグローバルインストールする
$ npm install -g @neos21/neos21

# パッケージを実行してみる
$ neos21
@neos21
http://neo.s21.xrea.com/

ご覧のとおり。


これで npm パッケージの作成から公開まではとりあえず試せた。

Node.js超入門

Node.js超入門

Angular v4.3 で追加された HttpClient を使ってみた

はじめてのAngular4 (I・O BOOKS)

はじめてのAngular4 (I・O BOOKS)

Angular v4.3 で新たに追加された HttpClient というモジュールを使ってみた。

これは既存の Http モジュールとは別モノで提供されていて、JSON のパースを勝手にやってくれたり、レスポンスの型指定ができたりと便利なようなので、ちょっとだけ使ってみた。

Angular v4.3 プロジェクトを用意する

前提環境は Angular CLI で作れる Angular アプリの雛形相当。これに Angular v4.3 のモジュール群をインストールする。

Angular は毎週パッチバージョンが上がるので、執筆時点では v4.3.2 になっている。npm outdated でバージョンを確認し、npm update@angular の各パッケージを v4.3.2 にアップデートする。npm-check-updates というパッケージを使えば一気に更新できるので、これをグローバルインストールして ncu -a とするのが楽かも。

HttpClient モジュールを追加する

次にアプリのモジュールに HttpClient モジュールを追加する。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';  // ← コレ

@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule  // ← コレ
  ],
  // 以下略
})
export class AppModule {}

HttpClient を使用するサービスを作る

次に HttpClient を使用するサービスを作る。ココでは GET・POST 通信をそれぞれ行うメソッドを用意した。

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';

/**
 * GET・POST 通信を行うサンプル
 */
@Injectable()
export class SampleService {
  /**
   * コンストラクタ
   *
   * @param http HttpClient を DI する
   */
  constructor(private http: HttpClient) { }

  /**
   * GET 通信のサンプル
   *
   * @return GET 通信の結果を持った Promise
   */
  get(): Promise<any> {
    const url = 'http://example.com/sample-api';
    const myParameter = 'MyParameterValue';

    return this.http.get(url, {
      params: new HttpParams().set('myParameter', myParameterValue);
    }).toPromise();
  }

  /**
   * POST 通信のサンプル

   * @return POST 通信の結果を持った Promise
   */
  save(): Promise<any> {
    const url = 'http://example.com/sample-api';
    const body = {
      myPostData: 'MyPostDataValue'
    };

    return this.http.post(url, body).toPromise();
  }
}

GET 通信のサンプル

一番簡単な GET 通信のサンプルは以下のとおり。

this.http.get(url)
  .subscribe((response) => {
    // response は Object 型
  });

これで指定の URL に GET 通信ができる。

これまでの Http モジュールは戻り値が Observable<Response> であり、JSON パースする必要があったが、HttpClient では Observable<Object> で返されるので JSON パースが要らなくなった。

上述の SampleService では、パラメータを指定している他、Observable を Promise に変換している。以下のように扱うことができる。

this.http.get(url, {
  params: new HttpParams().set('myParameter', 'MyParameterValue');
  // レスポンスのフォーマットを指定する場合は以下
  responseType: 'text'
})
  .toPromise()
  .then((response) => {
    // 処理
  });

これで、【url】?myParameter=MyParameterValue という URL で GET 通信したのと同じ結果が得られる。

POST 通信のサンプル

POST 通信の場合も、基本的なやり方は同じ。

this.http.post(url, {
  myPostData: 'MyPostDataValue'
})
  .subscribe((response) => {
    // 成功
  }, (error) => {
    // 失敗
  });

GET パラメータに対応する、POST 時の body は Object で記せば良い。

これも SampleService の方では Promise 化している。

this.http.post(url, body)
  .toPromise()
  .then((response) => {
    // 成功
  })
  .catch((error) => {
    // 失敗
  });

ユニットテストのやり方

HttpClient モジュールはユニットテストでのモック化も楽になっている。少しだけつまづいたところがあるので紹介。

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { inject, TestBed } from '@angular/core/testing';

import { SampleService } from './sample.service';

describe('SampleService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [SampleService]
    });
  });
  
  // テスト対象サービス
  let sut;
  // 通信先のモック
  let httpMock
  // テスト対象サービス・モックの用意
  beforeEach(inject([SampleService, HttpTestingController], (sampleService: SampleService, httpTestingController: HttpTestingController) => {
    sut = sampleService;
    httpMock = httpTestingController;
  }));
  
  it('GET 通信を行う', () => {
    // アクセスを期待する URL : HttpParams を指定している場合はパラメータを含めて URL とする
    const url = 'http://example.com/sample-api?myParameter=MyParameterValue';
    // モックの戻り値
    const result = 'Mock GET Result';
    
    // テスト対象関数の実行
    sut.get()
      .then((data) => {
        // モックとして返却したデータが受け取れていること
        expect(data).toEqual(result);
      })
      .catch((error) => {
        fail(`GET 通信のテストに失敗 : ${error}`);
      });
    
    // モック API を用意する
    const request = httpMock.expectOne(url);
    // モック API からの応答を返す
    request.flush(result);
    // モック化した API がコールされたか検証する
    httpMock.verify();
  });
  
  it('POST 通信を行う', () => {
    // アクセスを期待する URL
    const url = 'http://example.com/sample-api';
    // モックの戻り値
    const result = 'Mock POST Result';
    
    // テスト対象関数の実行
    service.post()
      .then((data) => {
        // モックとして返却したデータが受け取れていること
        expect(data).toEqual(result);
      })
      .catch((error) => {
        fail(`POST 通信のテストに失敗 : ${error}`);
      });
    
    // モック API を用意する
    const request = httpMock.expectOne(url);
    // モック API からの応答を返す
    request.flush(result);
    // モック化した API がコールされたか検証する
    httpMock.verify();
  });
});
  • テスト時は HttpClientTestingModuleimports に指定する。
  • HttpTestingController がモック API を担当する。HttpTestingController#expectOne() の引数に指定した URL に対してアクセスがあれば OK となる。
  • GET 通信にパラメータを指定している場合は、パラメータを含めて URL が一致しないとテストが通らない。
  • HttpTestingController#verify() で、「アクセスを待ち構えていたけど呼ばれなかった URL」が分かったりする。

こんな感じ。他にも色々便利な機能があるっぽいけど、新しすぎて文献不足。

参考

「Observable って何?」という方は以下などをドウゾ。簡単に言うと高機能 Promise。

ドスパラのデスクトップゲーミング PC「Galleria XG」を買った!

ドスパラのデスクトップゲーミング PC、ガレリア XG を BTO でカスタムして購入した。


ガレリア XG カスタム買いましたー!!!!!(・∀・)ウティー

これまで使っていたデスクトップ PC

これまでは Acer の ASM5811-A61 というデスクトップ PC を使っていた。

  • CPU:Core i5 750 2.66GHz
  • メモリ:2GB → 8GB まで拡張
  • ビデオカード:GeForce 310 → GeForce GTX550Ti に差替

とまぁこんなスペックで、購入した2010年当時ではそれなりに良いスペックだった。

去年2016年の6月に MacBookPro を買い、転職したら仕事でも SSD のパソコンを使うことが当たり前になったので、いいかげんデスクトップ PC も買い換えるか…ということで、買った。

ドスパラのガレリアシリーズ

ドスパラの「ガレリア」シリーズはコスパの高いゲーミング PC として有名で、値段の安さはマウスコンピュータかそれ以上だったりする。

その中でも今回は、ガレリア XG というモデルを選択し、カスタマイズした。

主なスペックは以下のとおり。太字にした部分がアップグレードしたところ

  • CPU:Intel Core i7-7700K 4.2GHz
  • メモリ:32GB DDR4
  • ビデオカード:NVIDIA GeForce GTX1080 8GB
  • SSD:500GB (無料増量キャンペーン中だった)
  • HDD:2TB
  • ブルーレイドライブ (読み書き可能)
  • USB ポート
    • 前面:USB3.0 ×2
    • 背面:USB2.0 ×2・USB3.0 ×4

これでお値段24万円と、スペックからしたら激安。というか MacBookPro より5万以上安いんだけど…。

注文から到着まで

7/29 (土) に思い立って勢いで注文したのだが、なんと 7/31 (月) には発送の連絡があり、8/2 (水) には自宅に届くところだった。所用があって受取を 8/4 (金) に変更したが、注文してから3・4日で受け取れることになる。

これまで使ってた PC と比べると二回りくらいデカいぞ……

Acer と比べると本体が二回りくらい大きい。

使ってみての感想

SSD のおかげなのか、CPU・GPU のおかげなのか、もはやどれのおかげか分からないが、恐ろしく高速。特に起動の速さは HDD には戻れなくなる。

普段使っている Firefox ブラウザはメモリをかなり食ってしまい、ウイルスバスターとの組み合わせでものすごくメモリを食っていたのだが、32GB もメモリがあると全く気にならない。

GTAIV・GTAV などのゲームは、解像度 1280x720 で画質「中」程度でそれなりにプレイできるぐらいだったのが、CPU・GPU が最高なヤーツなので、1920x1080 で最高画質にしてもヌルヌル動く。GTAV は MSAA をオンにするとさすがにカクつく場面があるので、これだけオフにしているが、それ以外は最高設定にしてもヌルッヌル。

Adobe Premiere Pro で動画編集もしてみたが、1080p の動画をサックサク編集できる。プロキシと呼ばれる低解像度ファイルを生成しなくてもストレスなく編集できるし、書き出しも物凄く速い。

高スペックなためか、吸気口が本体の側面と上部に大きく取られている。特に上部の吸気口はゴミが入りやすそうなので、何かメッシュでも軽く被せておいて、ゴミを避けつつ吸気させるようにしたい。

動作音はとても静か。静音まんぞくパックとやらのおかげかな?ゲームをしたり高負荷をかけても全然気になるような音が出ない。

スリープ状態にした時の、電源のブルー LED が若干眩しいので、適宜塞いでおくといいかも笑


このスペックをこの値段で買えるのはドスパラだけだと思う。「ゲーミング PC」というとゲーム専用みたいな気がしてしまうが、ゲームだけでなく、Photoshop を使うとか、動画編集をするとかいうユーザであれば、ゲーミング PC に求めるスペックが揃っていることもあるので、見てみると良いだろう。

7年ぶりに Windows マシンをゼロからセットアップしたので、そこで遭遇したアレコレも今後記事にしていこうと思う。