Google Web Starter Kitのgulpfileを翻訳してみた

![web-starter-kit.png](https://qiita-image-store.s3.amazonaws.com/0/36099/d384da89-8b39-cf44-a743-5a47d4e7d471.png)

[Google Web Starter Kit](https://github.com/google/web-starter-kit)
[GitHub - google/web-starter-kit](https://github.com/google/web-starter-kit)

javascriptを覚えるために静的開発環境を整えようとして、タスクランナーフレームワークgulpを導入。
ついでにcssフレームワークは話題のGoogle Web Starter Kitを使ってみる。

Google Web Starter Kitの純正gulpfileを読んで注釈をつけてみたので、投稿。

# use scrict

```js
'use strict';
```

ストリクトモード（厳格モード）宣言。  
開発者がよりエラーを探しやすくするよう、厳格なエラーチェックが行われるモード。

# Include
```js
// Include Gulp & Tools We'll Use
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var pagespeed = require('psi');
var reload = browserSync.reload;
```

以下のパッケージを変数として宣言

- gulp
- gulp-load-plugins
- gulp-del
- gulp-run-sequence
- gulp-browser-sync
- gulp-pagespeed
- gulp-reload

# autoprefixer
```js
var AUTOPREFIXER_BROWSERS = [
  'ie >= 10',
  'ie_mob >= 10',
  'ff >= 30',
  'chrome >= 34',
  'safari >= 7',
  'opera >= 23',
  'ios >= 7',
  'android >= 4.4',
  'bb >= 10'
];
```

ブラウザオートプレフィックス設定。  
[gulp-autoprefixer](https://www.npmjs.org/package/gulp-autoprefixer)

# Lint Javascript
```js
// Lint JavaScript
gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});
```

Lint JavaScriptを設定。  
jsの構文チェックをしてくれる。  
`app/scripts`以下の全てのjsファイルが対象。  
browserSyncがアクティブでなければ、jshistが動かない。  
[gulp-jshist](https://www.npmjs.org/package/gulp-jshint)

# Optimize Images
```js
// Optimize Images
gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true
    })))
    .pipe(gulp.dest('dist/images'))
    .pipe($.size({title: 'images'}));
});
```

画像の圧縮処理後、`dist/images`に出力。  
サイズをコンソールへ出力。  
`app/images`以下の全てのファイルが対象。  
[gulp-imagemin](https://www.npmjs.org/package/gulp-imagemin)

# Copy All Files At The Root Level (app)
```js
// Copy All Files At The Root Level (app)
gulp.task('copy', function () {
  return gulp.src(['app/*','!app/*.html'], {dot: true})
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'copy'}));
});
```

`app`フォルダに存在する__htmlファイルを除く__全てのファイルを`dist`に出力。  
階層化された（`app`ルートより深い）ファイルはコピーされない。  
その後サイズをコンソールへ出力。

# Copy Web Fonts To Dist
```js
// Copy Web Fonts To Dist
gulp.task('fonts', function () {
  return gulp.src(['app/fonts/**'])
    .pipe(gulp.dest('dist/fonts'))
    .pipe($.size({title: 'fonts'}));
});
```

`app/fonts`以下の全てのファイルを`dist/fonts`へ出力。  
その後サイズをコンソールへ出力。

# AUtomaticallu Prefix CSS
```js
// Automatically Prefix CSS
gulp.task('styles:css', function () {
  return gulp.src('app/styles/**/*.css')
    .pipe($.changed('app/styles'))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('app/styles'))
    .pipe($.size({title: 'styles:css'}));
});
```

`app/styles/`以下の全てのCSSファイルを対象に、ブラウザプレフィックスを自動で付ける。  
その後サイズをコンソール出力。  
出力先フォルダが同じところだということにも注意。

# Compile Sass For Style Guide Components (app/styles/components)
```js
// Compile Sass For Style Guide Components (app/styles/components)
gulp.task('styles:components', function () {
  return gulp.src('app/styles/components/components.scss')
    .pipe($.rubySass({
      style: 'expanded',
      precision: 10,
      loadPath: ['app/styles/components']
    }))
    .on('error', console.error.bind(console))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('app/styles/components'))
    .pipe($.size({title: 'styles:components'}));
});
```

`app/styles/components/components.scss`のSASSコンパイルを行う。  
オプションは表記通り。  
エラーの場合はコンソールへ出力。  
ブラウザプレフィックスを自動で付ける。  
出力先は`app/styles/components`。  
サイズをコンソール出力。

# Compile Any Other Sass Files You Added (app/styles)
```js
// Compile Any Other Sass Files You Added (app/styles)
gulp.task('styles:scss', function () {
  return gulp.src(['app/styles/**/*.scss', '!app/styles/components/components.scss'])
    .pipe($.rubySass({
      style: 'expanded',
      precision: 10,
      loadPath: ['app/styles']
    }))
    .on('error', console.error.bind(console))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp/styles'))
    .pipe($.size({title: 'styles:scss'}));
});
```

`app/styles/**/*.scss`以下の`components.scss`を除く全てのSASSファイルをコンパイル。  
オプションは表記通り。  
エラーの場合はコンソールへ出力。  
ブラウザプレフィックスを自動で付ける。  
出力先は`.tmp/styles`。  
サイズをコンソール出力。


# Output Final CSS Styles
```js
// Output Final CSS Styles
gulp.task('styles', ['styles:components', 'styles:scss', 'styles:css']);
```

上記の３つの`styles:`で定義したタスクをまとめて実行。  
並列処理される。

# Scan Your HTML Fot Assets & Optimize Them
```js
// Scan Your HTML For Assets & Optimize Them
gulp.task('html', function () {
  return gulp.src('app/**/*.html')
    .pipe($.useref.assets({searchPath: '{.tmp,app}'}))
    // Concatenate And Minify JavaScript
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    // Remove Any Unused CSS
    // Note: If not using the Style Guide, you can delete it from
    // the next line to only include styles your project uses.
    .pipe($.if('*.css', $.uncss({
      html: [
        'app/index.html',
        'app/styleguide/index.html'
      ],
      // CSS Selectors for UnCSS to ignore
      ignore: [
        '.navdrawer-container.open',
        /.app-bar.open/
      ]
    })))
    // Concatenate And Minify Styles
    .pipe($.if('*.css', $.csso()))
    .pipe($.useref.restore())
    .pipe($.useref())
    // Update Production Style Guide Paths
    .pipe($.replace('components/components.css', 'components/main.min.css'))
    // Minify Any HTML
    .pipe($.if('*.html', $.minifyHtml()))
    // Output Files
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'html'}));
});
```

`app`フォルダ以下の全てのhtmlファイルを対象に、本番環境用にコードを削除。  
例としては`app/index.html`の28〜32行目を削除する。  
次に全ての`app`以下のjsファイルを対象に、ひとつのjsファイルに結合と圧縮をする。  
次に全ての`app`以下のCSSファイルを対象に、`app/index.html`と`app/styleguide/index.html`の中で使われていないセレクタへのスタイルを自動削除。  
CSSセレクタ`.navdrawer-container.open`、`.app-bar.open`は除く。  
その後全てのCSSファイルをひとつに結合、圧縮。  
`components/components.css`を`components/main.min.css`にリネーム。  
`app`以下の全てのhtmlファイルを圧縮。  
上記で生成されたファイルを`dist`に出力。  
サイズをコンソール出力。

# Clean Output Directory
```js
// Clean Output Directory
gulp.task('clean', del.bind(null, ['.tmp', 'dist']));
```

`.tmp`、`dist`フォルダを削除。

# Watch Files For Changes & Reload
```js
// Watch Files For Changes & Reload
gulp.task('serve', function () {
  browserSync({
    notify: false,
    // Run as an https by uncommenting 'https: true'
    // Note: this uses an unsigned certificate which on first access
    //       will present a certificate warning in the browser.
    // https: true,
    server: {
      baseDir: ['.tmp', 'app']
    }
  });

  gulp.watch(['app/**/*.html'], reload);
  gulp.watch(['app/styles/**/*.scss'], ['styles:components', 'styles:scss']);
  gulp.watch(['{.tmp,app}/styles/**/*.css'], ['styles:css', reload]);
  gulp.watch(['app/scripts/**/*.js'], ['jshint']);
  gulp.watch(['app/images/**/*'], reload);
});
```

`.tmp`と`app`フォルダをルートとして仮想サーバーを立てる。  
browserSyncを起動。  
同フォルダでファイルの変更があった場合ブラウザをリロード。

# Build and serve the output from the dist build
```js
// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], function () {
  browserSync({
    notify: false,
    // Run as an https by uncommenting 'https: true'
    // Note: this uses an unsigned certificate which on first access
    //       will present a certificate warning in the browser.
    // https: true,
    server: {
      baseDir: 'dist'
    }
  });
});
```

本番環境用の`dist`フォルダをルートとして仮想サーバーを立てる。

# Build Production Files, the Default Task
```js
// Build Production Files, the Default Task
gulp.task('default', ['clean'], function (cb) {
  runSequence('styles', ['jshint', 'html', 'images', 'fonts', 'copy'], cb);
});
```

`gulp`コマンドでデフォルトで処理されるタスクを設定。  
まず`clean`タスクを行い、終了後、`runSequence`プラグインの効果で、  
`style`タスクが処理されたあと、`jshint`、`html`、`images`、`fonts`、`copy`のタスクを平行処理する。

# Run PageSpeed Insights
```js
// Run PageSpeed Insights
// Update `url` below to the public URL for your site
gulp.task('pagespeed', pagespeed.bind(null, {
  // By default, we use the PageSpeed Insights
  // free (no API key) tier. You can use a Google
  // Developer API key if you have one. See
  // http://goo.gl/RkN0vE for info key: 'YOUR_API_KEY'
  url: 'https://example.com',
  strategy: 'mobile'
}));
```

`gulp pagespeed`コマンドでGoogle Page Speed Insightsを使用できる。

# Load custom tasks from the `tasks` directory
```js
// Load custom tasks from the `tasks` directory
try { require('require-dir')('tasks'); } catch (err) {}
```

自分のタスクをロードする用。

# まとめ
勉強になった。
タスクのまとめ方が綺麗。
直列処理させたいときや、if文で動作判定したいときに参考になりそう。
UnCSSは知らないパッケージだったので目から鱗。

注釈間違っているところがあれば是非コメントください！