Node製の静的サイトジェネレータを探す

GruntやらGulpやらReactやらですっかりJavaScriptづいているので、Middlemanの代わりに何かNode.js系の静的サイトジェネレータがないか物色。

- Slimに似ていてタイプ量が少なそうなJadeを使いたい
- CSSとJavaScriptのビルドは自前でも可能なので機能としては必要ない

タスクランナーと併用したり、外部のパッケージを噛ませたりできる汎用性があるとよい。HTML関係以外はgulp+npmでできるので、HTMLのあれやこれやができて軽いほうが良い、といったところが選ぶ基準です。

```js
// 想像上の構成
var gulp = require('gulp');
var xxx = require('xxx');//HTMLのテンプレやパスを処理してくれるパッケージ!!!
var prettify = require('gulp-prettify');//納品ファイルなのでprittyにしたい
var sass = require('gulp-sass');//sassがあればなにも問題ない
var autoprefixer = require('gulp-autoprefixer');//これも必須ですね
var browserify = require('browserify');//魔法の杖
var babelify = require('babelify');//もうES６でいいよね？
var watchify = require('watchify');//差分ビルド…小規模なら必要ないかも
var browsersync = require('browser-sync');//server&livereload超便利
```

[StaticGen](https://www.staticgen.com/)という静的サイトジェネレータの比較サイトを見つけたので、そこからJavaScript製で人気がありそうなツールを見てみました。

# 候補

## [GitBook](https://github.com/GitbookIO/gitbook)

**“A modern publishing toolchain.”**

サイトのほかeBookやPDFを生成できる。スターは圧倒的だけど静的サイトとしてはどうなんでしょう？ターゲットが違う気がするので今回はパス。（未検証）

## [Hexo](https://github.com/hexojs/hexo)

**“Hexo is a fast, simple and powerful blog framework.”**

ブログフレームワークとあるので今回はパス。（未検証）

## [Brunch](https://github.com/brunch/brunch)

**“An ultra-fast HTML5 build tool. Capable of static site generation.”**

悪くなさそうだけど、ドキュメントの印象がなんかめんどくさそう…実際に少しさわってみましたがコンセプトがいまいち理解できませんでした。

## [Metalsmith](https://github.com/metalsmith/metalsmith)

**“An extremely simple, pluggable static site generator.”**

なんかGulpっぽいしいいかも？と思ったがツールとして閉じているのが気になる。

EVERYTHING IS A PLUGINと掲げており、本体とプロパーのプラグインでいろいろまかなうという方向性のようですが、すべての依存がちゃんと更新され、解決されるのか不安です。

プラグインといっても1ファイルで済むような簡単なものもありますが、既存のプラグインでできないことが発生したとき、一段障壁が高いかなと思いました。系統だったドキュメントがないのも痛いです。

もともとはhandlebarsの使用を想定しており、jadeを使ったテンプレートはlivereloadでは更新されず、コンテンツファイルのいずれかを変更してトリガーを引く必要がありました。

掲載サンプルの多いブログ形式のサイトならうまく使えるのかも知れません。

### Metalsmithの構成例

```js

// index.js

'use strict';

var Metalsmith = require('metalsmith');
var markdown   = require('metalsmith-markdown');
var jade       = require('metalsmith-jade');
var rootpath   = require('metalsmith-rootpath');
var layouts    = require('metalsmith-layouts');
var sass       = require('metalsmith-sass');
var serve      = require('metalsmith-serve');
var watch      = require('metalsmith-watch');
var beautify   = require('metalsmith-beautify');
var ignore     = require('metalsmith-ignore');

Metalsmith(__dirname)
  .use(jade({ pretty:false }))
  .use(markdown())
  .use(rootpath())
  .use(sass({ outputDir: 'css/' }))
  .destination('./dist')
  .use(serve({
    port: 3000,
    verbose: true
  }))
  .use(watch({
    paths: {
      "${source}/**/*": "**/*.{md,jade,sass}"
    },
    livereload: true
  }))
  .use(layouts({
    engine: 'jade'
  }))
  .use(beautify({
    indent_size: 2,
    indent_char: ' ',
    js: false
  }))
  .build(function (err) {
    if(err) console.log(err)
  })
```

- [Metalsmithを使ってみたサンプル](https://github.com/110chang/metalsmith-test)

### 追記

この方法も試してみたい

http://bourcereau.fr/en/blog/using-metalsmith-with-jade/
## [Harp](http://harpjs.com/)

**“Harp is a static web server that can also compile your project down to static assets.”**

使いそうな機能が揃っていて、シンプルでよさ気。開発が続くかどうかが気になる。

細かいところが追いついていない感じはあるが、小規模なサイトをコンパイルするだけならいけそう。Middlemanを小さくしてNode製にしたような印象。

- メタデータをglobalsと各ディレクトリに設定しておける
- ファイルツリーの情報がpublicに格納されている
- currentに現在のファイル名と親からのリストが格納されている
- 画像等のアセットにイテレータでアクセスできる

これだけで、使う方としては安心感があります。

sassはHarpにコンパイルさせてもよさげですし、スクリプトはJavaScriptをそのまま理解してくれるので、バンドルしたものをソースディレクトリに突っ込めばいいだけです。コンパイル時はそのままコピーされます。

各ディレクトリの_data.jsonにメタデータが分散しているのが気になるといえば気になりますが、globalsを使えばなんとでもなりそうです。frontmatterも使えればいいのですが。

### Harpの構成例

```js

// gulpfile.js

var harp = require('harp');
var gulp = require('gulp');
var browsersync = require('browser-sync');
var exec = require('child_process').exec;

gulp.task('server', function() {
  harp.server(__dirname + '/public', {
    port: 3000
  }, function() {});

  browsersync.init({
    proxy: 'http://localhost:3000/',
    port: 3333
  });
});

gulp.task('default', ['server'], function() {
  gulp.watch('./public/**/*', function() {
    browsersync.reload();
  });
});

gulp.task('compile', function() {
  exec('harp compile ./public ./build', function(err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
    //cb(err);
  });
});
```

- [Harpを使ってみたサンプル](https://github.com/110chang/harp-test)

私の目的としてはHarpがかなり期待できそうです。