開発用・簡易Webサーバー/プロクシサーバーkokoをつくった


つくりました。当初やりたかったところまで実装終わったのでご紹介。
githubとnpmで公開中です。

- [fnobi/koko · GitHub](https://github.com/fnobi/koko)
- [koko](https://npmjs.org/package/koko)

## どんなもの?

クライアントサイドの開発をするときに、速攻で起動するサーバーです。
ざっくり言うと、コマンド一発で起動できるwebrickあるいは[charles](http://www.charlesproxy.com/)みたいなもの?

インストールは、nodeをインストールした上で、以下。

```bash
% npm -g install koko
```

使い方はこんな感じ。

```bash
% cd ~/Desktop/project/
% ls
css		index.html	js
% koko 
document root	: /Users/fnobi/Desktop/project
[listen 4299]
```

これで、ブラウザで```http://localhost:4299```にアクセスすれば、
```/Users/fnobi/Desktop/project```をドキュメントルートにしたサーバーにアクセスできるというわけです。

## いいところ

### 1, 起動が早い

名前の由来は、**「とにかくここが見たいんじゃ!」**の「ここ」です。
そんな雰囲気なので、とにかくすぐ起動できることを重視してます。

プロジェクトディレクトリに行って``` koko ```だけ打てば起動されますし、
さらに```koko -o```と打てば、**ブラウザが勝手に起動してくれます**。(※Mac限定)

```bash
% koko -o
document root	: /Users/fujisawa-shin/Desktop/project
[listen 14535]
[open http://localhost:14535/]
(→デフォルトブラウザが立ち上がって、http://localhost:14535が開く)
```

### 2, 使用ポートをランダムに選択

plackupとかweblickのワンライナーでも、似たようなことできるんですが、
ポートは起動時の決め打ちになっているので、2つ以上同時に起動するときは、いちいちポート番号を考えなくちゃいけません。

これがだるいので、kokoでは**適当に空いてるポートを見つけてきて使う**形になっています。
(上のサンプルでも、実際ちがうポートが使われています)

-oオプションを使うとブラウザの起動までやってくれるので、
ポート番号をブラウザにコピペする手間もありません。

### 3, proxy serverにもなる

たとえば、既に公開されている http://fnobi.com というサイトの、
index.htmlだけ修正したい場合。

http://fnobi.com を作っているファイル全部をローカルでそろえてもいいですが、Webアプリケーションの場合は結構厄介です。
そこで、kokoのproxy server機能を使えば、手元ではindex.htmlだけ用意すればOKになります。

```bash
% mkdir fnobi.com
% cd fnobi.com
% curl -O http://fnobi.com/index.html
% koko -u http://fnobi.com -o
document root: /Users/fujisawa-shin/Desktop/fnobi.com
proxy: fnobi.com:80
[listen 51434]
[open http://localhost:51434/]
```

これでhttp://localhost:51434では、

- 手元にファイルがある場合はそれを参照 (この場合index.htmlだけ)
- その他のアクセスは http://fnobi.com からとってきて参照 (その他の画像やjsなどのファイル)

という形になります。わーい。

「サーバー環境をローカルに構築するとかムリ! ぼくフロント専門!」
という方にもおすすめです。

### 4, gruntに対応

先日、grunt-pluginも作成しました。

- https://github.com/fnobi/grunt-koko

インストールはこんな感じで。

```bash
% cd your/grunt/project/root
% npm install grunt-koko --save-dev
```

これをGruntfileでloadすれば、
taskとしてkokoの起動ができます。

```javascript:Gruntfile.js
// Gruntfileのサンプル
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        koko: {
            dev: { // dev環境でのkoko設定
                openPath: '/'
            },
            debug: { // debug環境でのkoko設定
                openPath: '/top.html',
                proxyURL: 'http://fnobi.com/'
            }
        }
    });

    grunt.loadNpmTasks('grunt-koko');

    grunt.registerTask('default', ['koko:dev']);
};
```

これで、koko起動時にブラウザを開くか、proxyのURLをどうするかなどを、
オプションで書かなくても済むようになります。やっほい!

```bash
% grunt koko:debug
document root: /Users/fujisawa-shin/Desktop/fnobi.com
proxy: fnobi.com:80
[listen 51434]
[open http://localhost:51434/top.html]
```

特にproxyのURLについては、プロジェクトごとに決まっていることが多いと思うので、
gruntを導入しているプロジェクトではぜひ使ってみてください。


## 不便なところ

### 1, 使用ポートをランダムに選択してしまう
これはすなわち、同じプロジェクトでも、
起動するたびに開発用URLが変わってくるということなので面倒っちゃ面倒です。

いま、プロジェクトごとにポートを固定する機能とか付けようかなぁとも思ってますが、
とりあえずは-oオプションがあるので、そんなに気にならないかも。


### 2, proxy serverとしては雑

[charles](http://www.charlesproxy.com/)みたいに、ブラウザにまで干渉するタイプのproxy serverではないです。

たとえば```http://fnobi.com```のproxyとして起動した状態では、

```<script src="/js/main.js"></script>```と指定されていたら、手元のjs/main.jsを参照しますが、
```<script src="http://fnobi.com/js/main.js">```とhttpから指定されていたら、オリジナルの方が出ます。
 
これはちょっと現在の仕様だとしょうがない。

他にも、charlesはオプションがもっといろいろあったり、
アクセスの解析もできたりと多機能ですが、そういうのはできないです。


## 開発意図
クライアントサイドの開発時に、
MacならApacheを入れておいて~/Sitesを使うのが早いし、
nginxを立てておくんでもいいんですが、

やっぱり、開発中でないものにまで常時アクセスできるようになっていると鬱陶しいし、
```http://localhost/~(ユーザー名)/...```って感じのURLを覚えるのも地味に面倒くさい。

そこで、プロジェクトごとに開発用のサーバーを立てることを考えたんですが、
plackupとかwebrickも、ワンライナーが長くて面倒くさい。

- 参考: [簡単に手元でHTTPのファイルサーバ立てる方法 - かみぽわーる](http://blog.kamipo.net/entry/2013/02/20/122225)

そんなわけで、nodeだとサーバー作るの簡単だし、さらっと書こう! と思ったのがきっかけです。

その後、せっかくだしproxy serverも付けよう! とか思いついていまの形になりました。
が、個人的にはただのWebサーバーでもだいたい満足してます。

npmの[http-proxy](http://npmjs.org/package/http-proxy)の使い方を調べたり、
ついでに[empty-port](http://npmjs.org/package/empty-port)っていうパッケージを書いたり、勉強になりました。

empty-portもそれなりに便利なので、また使うかも。
(ただし、もう少し賢いrandom port実装はあるみたい)

## まとめ

自分でもがっつり使うツールができたのはいいことです。
みなさまもよろしければ、インストールしてみてください。

バグやご要望は https://github.com/fnobi/koko/issues まで!