読者です 読者をやめる 読者になる 読者になる

Rails Webook

自社のECを開発している会社で働いています。Rails情報やサービスを成長させる方法を書いていきます

Railsにgulpを統合させる

gulp assets

f:id:nipe880324:20151218024113p:plain:w420

Railsでgulpを使ってアセットファイルの管理できる環境を構築します。
gulpはアセットを管理するツールで、js、css、imagesなどのアセットファイルをビルドして、それをRailsから参照する流れです。
また、gemにバンドルされているアセットファイルもあるので、Sprockets(Railsのアセット管理のgem)は有効にしておきます。有効にしておきますが極力使いません。

gulpでsass/scssのコンパイル、ES6のコンパイル(babel, webpack)、gulpの便利プラグイン(変更監視、画面リロード、通知)、ミニファイ、ダイジェスト付与をできるようにします。
そして、gulpで作成されたcssやjsのアセットファイルをRailsからロードできるようにします。

参考にソースファイルをGitHubに上げたあります。
https://github.com/nipe0324/rails_with_gulp

動作確認バージョン

  • Ruby 2.2.2
  • Rails 4.2.3
  • gulp 3.9.0
  • webpack 1.12.9
  • babel 6.3.13
  • その他のnpmライブラリはpackage.jsonを見てください

1. railsの作成

Railsプロジェクトを作成します。

Railsプロジェクトの作成

rails new rails_with_gulp


.gitignoreの一番下にnode_modulesを追加しておきます。

// .gitignore
..

+ # npm packages
+ node_modules

+ # ignore public/assets for compiled assets by gulp
+ /public/assets


ジェネレーターでjavascriptcssを作成されないようにします。

  # config/application.rb
  ...

  module RailsWithGulp
    class Application < Rails::Application
      ...

      # Do not swallow errors in after_commit/after_rollback callbacks.
      config.active_record.raise_in_transactional_callbacks = true

+     # Do not generate asset files
+     config.generators do |g|
+       g.assets false
+     end
    end
  end

application.jsapplication.cssは極力使わないようにするので、記述を削除します。

# app/assets/javascripts/application.js

  //
- //= require jquery
- //= require jquery_ujs
- //= require turbolinks
- //= require_tree .


# app/assets/stylesheets/application.js
   *
-  *= require_tree .
-  *= require_self
   */


確認用にTopコントローラーを作成します。

rails g controller Top index


top#indexをルートに設定しておきます。

  # config/routes.rb
  Rails.application.routes.draw do
*   root 'top#index'
    ...

2. gulpのインストール

Railsにgulpをインストールしていきます。

package.jsonの作成

まず、gulpも含めたJavascriptのライブラリをnpmを使って管理するためpackage.jsonを作成します。

npm init -y


-ypackage.jsonを作るときの質問ですべてyesを選択するオプションです。
npmはNode Package Managerの略で、最近はJSのライブラリを管理するために使われています。
npmNode.jsをインストールすると一緒にインストールされます。

作成されたpackage.jsonは次のとおりです。
プロジェクトの基本的な情報が記載されています。ここに依存するライブラリも後ほど追加していきます。

// package.json
{
  "name": "rails_with_gulp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/nipe0324/rails_with_gulp.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/nipe0324/rails_with_gulp/issues"
  },
  "homepage": "https://github.com/nipe0324/rails_with_gulp#readme"
}


gulpのインストール

gulpをグローバル(-gオプション)とプロジェクト(--save-devオプション)にインストールします。

npm install -g gulp
npm install --save-dev gulp


gulpfile.jsの作成

gulpのエントリポイントはgulpfile.jsとなりますので作成します。

// gulpfile.js
+ var requireDir = require('require-dir');
+ requireDir('./gulp/tasks', { recurse: true }); // recurse: true はサブディレクトリもrequireする

require-dirは指定したディレクトリをrequireできるので、一気に多くのファイルをrequireしたい時に便利です。
gulpfile.jsに直接gulpのタスクを記載してもよいですが、タスクが増えた場合に見づらくなるので、gulp/tasks配下にタスクごとにファイルを作成し、require-dirですべてのタスクファイルを読み込むようにします。

mkdir -p gulp/tasks

require-dirをインストールしていないので、npm installコマンドでインストールします。

npm install --save-dev require-dir


コンフィグファイルの作成

config.jsを作成し、設定値をここにまとめます。

// gulp/tasks/config.js

+ // gulpのアセットファイルを配置する場所
+ gulpAssets   = 'gulp/assets';
+ // publicのアセットファイルを配置する場所
+ publicAssets = 'public/assets';
+
+ module.exports = {
+   gulpAssets:   gulpAssets,
+   publicAssets: publicAssets,
+
+   javascript: {
+     src:  gulpAssets   + '/javascripts/**/*',
+     dest: publicAssets + '/javascripts'
+   },
+   stylesheet: {
+     srcSass:  gulpAssets   + '/stylesheets/**/*.sass',
+     srcScss:  gulpAssets   + '/stylesheets/**/*.scss',
+     dest: publicAssets + '/stylesheets'
+   },
+   watch: {
+     javascript:     gulpAssets + '/javascripts/**/*',
+     stylesheetSass: gulpAssets + '/stylesheets/**/*.sass',
+     stylesheetScss: gulpAssets + '/stylesheets/**/*.scss',
+     browserSync: 'public/**/*'
+   },
+   browserSync: {
+     proxy: 'localhost:3000'
+   },
+   rev: {
+     dest: publicAssets + '/rev-manifest.json',
+     opts: {
+       base:  process.cwd() + '/' + publicAssets,
+       merge: true
+     }
+   }
+ }


gulpのタスクを作成

まずは、public/assetsディレクトリを削除するcleanタスクを作成します。
delを使うことで、フォルダやファイルを削除できます。

npm install --save-dev del

clean.jsファイルを作成し、delプラグインを使用してファイルを削除します。

// gulp/tasks/clean.js
+ var config = require('./config');
+ var gulp = require('gulp');
+ var del  = require('del');
+
+ gulp.task('clean', function() {
+   return del(config.publicAssets);
+ });

gulpのタスクを作成するには、gulp.task('<タスク名>', function() { <タスクの処理> })の形式で作成します。

では、gulp cleanコマンドを実行し、cleanタスクを実行し、public/assetsを削除します。

$ mkdir public/assets

$ gulp clean
[02:04:34] Using gulpfile ~/rails_with_gulp/gulpfile.js
[02:04:34] Starting 'clean'...
[02:04:34] Finished 'clean' after 5.24 ms

$ ls public/assets
ls: public/assets: No such file or directory


デフォルトタスクの作成

default.jsを作成し、defaultタスクを登録します。

// gulp/tasks/default.js
+ var gulp = require('gulp');
+
+ gulp.task('default', ['clean']);

gulpコマンドを実行するとdefaultタスクが実行されます。

$ gulp
[02:06:28] Using gulpfile ~/rails_with_gulp/gulpfile.js
[02:06:28] Starting 'clean'...
[02:06:28] Finished 'clean' after 4.48 ms
[02:06:28] Starting 'default'...
[02:06:28] Finished 'default' after 12 μs

3. sass/scssのコンパイル

gulpでsassscssコンパイルできるようにします。

Sassのコンパイル

まず、gulp-sassをインストールします。

npm install --save-dev gulp-sass

sassとscssをコンパイルするタスクのcompile-sasscompile-scssを作成します。

// gulp/tasks/sass_scss.js
+ var config = require('./config');
+ var gulp = require('gulp');
+ var sass = require('gulp-sass');
+
+ gulp.task('compile-sass', function() {
+   return gulp.src(config.stylesheet.srcSass)
+       .pipe(sass({ indentedSyntax: true, errLogToConsole: true }))
+       .pipe(gulp.dest(config.stylesheet.dest));
+ });
+
+ gulp.task('compile-scss', function() {
+   return gulp.src(config.stylesheet.srcScss)
+       .pipe(sass({ indentedSyntax: false, errLogToConsole: true }))
+       .pipe(gulp.dest(config.stylesheet.dest));
+ });

srcでインプットとなるファイルを指定し、sassでsass/scssファイルをコンパイルし、destで出力先を指定しています。


デフォルトのタスクを修正します。
cleanタスクでディレクトリを削除してから、sass/scssのコンパイルを処理したいのでrun-sequenceを使います。

npm install --save-dev run-sequence
  // gulp/tasks/default.js
  var gulp = require('gulp');
+ var runSequence = require('run-sequence');

* gulp.task('default', function() {
+   runSequence(
+     'clean', // まずcleanタスクを実行
+     ['compile-sass', 'compile-scss'] // 次に並列でコンパイル
+   );
* });


スタイルシートを配置するgulp/assets/stylesheetsディレクトリを作成します。

mkdir -p gulp/assets/stylesheets

そして、application.scssを作成します。

// gulp/assets/stylesheets/application.scss
+ body {
+   background-color: gray;
+
+   h1 {
+     color: white;
+   }
+ }

gulpコマンドでscssをコンパイルしてみます。

gulp

public/stylesheets/application.cssというファイルが作成されます。

body {
  background-color: blue; }
  body h1 {
    color: white; }


ファイル名を変更

ビルドで作られたファイルには、.bundleをつけるようにして、ビルドされたかどうかわかりやすくしたいと思います。
gulp-renameでファイル名を変更するようにします。

npm install --save-dev gulp-rename

renameでファイル名を変更できます。

// gulp/tasks/sass_scss.js
  var config = require('./config');
  var gulp = require('gulp');
  var sass = require('gulp-sass');
+ var rename = require('gulp-rename');

  gulp.task('compile-sass', function() {
    return gulp.src(config.stylesheet.srcSass)
        .pipe(sass({ indentedSyntax: true, errLogToConsole: true }))
+       .pipe(rename({ suffix: '.bundle' }))
        .pipe(gulp.dest(config.stylesheet.dest));
  });

  gulp.task('compile-scss', function() {
    return gulp.src(config.stylesheet.srcScss)
        .pipe(sass({ indentedSyntax: false, errLogToConsole: true }))
+       .pipe(rename({ suffix: '.bundle' }))
        .pipe(gulp.dest(config.stylesheet.dest));
  });


ファイル名にダイジェストを追加

unicorn.css => unicorn-d41d8cd98f.cssのようにファイル名にダイジェストを追加します。
gulp-revを使って、ダイジェストをつけれます。

npm install --save-dev gulp-rev

rev()でファイル名にダイジェストを追加し、rev.manifest(<ファイル名>)マニフェストファイルを作成し、gulp.destマニフェストファイルの配置先を指定しています。

// gulp/tasks/sass_scss.js
  var config = require('./config');
  var gulp = require('gulp');
  var sass = require('gulp-sass');
  var rename = require('gulp-rename');
+ var rev  = require('gulp-rev');

  gulp.task('compile-sass', function() {
    return gulp.src(config.stylesheet.srcSass)
        .pipe(sass({ indentedSyntax: true, errLogToConsole: true }))
        .pipe(rename({ suffix: '.bundle' }))
+       .pipe(rev())
*       .pipe(gulp.dest(config.stylesheet.dest))
+       .pipe(rev.manifest(config.rev.dest, config.rev.opts))
+       .pipe(gulp.dest(config.publicAssets))
  });

  gulp.task('compile-scss', function() {
    return gulp.src(config.stylesheet.srcScss)
        .pipe(sass({ indentedSyntax: false, errLogToConsole: true }))
        .pipe(rename({ suffix: '.bundle' }))
+       .pipe(rev())
*       .pipe(gulp.dest(config.stylesheet.dest))
+       .pipe(rev.manifest(config.rev.dest, config.rev.opts))
+       .pipe(gulp.dest(config.publicAssets))
  });

gulpでsass/scssをビルドすると、JSON形式でマニフェストファイルが作成されます。

// public/assets/rev-manifest.json
{
  "application.bundle.css": "application-b4f27b6d0b.bundle.css"
}


cssファイルのminify(ミニファイ)

cssファイルのファイルサイズを小さくすることでパフォーマンスが少し向上します。
gulp-minify-cssCSSをミニファイします。

npm install --save-dev gulp-minify-css

minifyCssでミニファイできます。

// gulp/tasks/sass_scss.js
  var config = require('./config');
  var gulp = require('gulp');
  var sass = require('gulp-sass');
  var rename = require('gulp-rename');
  var rev  = require('gulp-rev');
+ var minifyCss = require('gulp-minify-css');

  gulp.task('compile-sass', function() {
    return gulp.src(config.stylesheet.srcSass)
        .pipe(sass({ indentedSyntax: true, errLogToConsole: true }))
+       .pipe(minifyCss())
        .pipe(rename({ suffix: '.bundle' }))
        .pipe(rev())
        .pipe(gulp.dest(config.stylesheet.dest))
        .pipe(rev.manifest(config.rev.dest, config.rev.opts))
        .pipe(gulp.dest(config.publicAssets))
  });

  gulp.task('compile-scss', function() {
    return gulp.src(config.stylesheet.srcScss)
        .pipe(sass({ indentedSyntax: false, errLogToConsole: true }))
+       .pipe(minifyCss())
        .pipe(rename({ suffix: '.bundle' }))
        .pipe(rev())
        .pipe(gulp.dest(config.stylesheet.dest))
        .pipe(rev.manifest(config.rev.dest, config.rev.opts))
        .pipe(gulp.dest(config.publicAssets))
  });

gulpコマンドで作成されたcssファイルを見ると、
次のように、スペースが削除されている(ミニファイ)ことがわかります。

// public/assets/stylesheets/application-742938ec8.bundle.css
body{background-color:gray}body h1{color:red}


4. ES6のコンパイル

babelを使ってES6を使えるようにします。また、webpackを使うことで、jsファイル群の依存関係を管理するようにします。
※babelはES6をES5に変換するツール(トランスパイラ)です。トランスパイルすることで、ES6がまだ実装されていない段階でもES6の文法でjsファイルを記載でき、ES6のメリットを享受できます

webpackでコンパイル

webpackはモジュールバンドラで、js、jade、coffee、cssなど複数のファイルの依存関係を記載することで、webpackがいいかんじにまとめてくれるのでそれぞれのモジュールの独立性を保つことができます。
今回は、主に複数のjsを必要に応じてまとめあげるために利用します。

gulp-webpackをインストールします。

npm install --save-dev gulp-webpack


webpackタスクを作成します。

// gulp/tasks/webpack.js
+ var config        = require('./config');
+ var gulp          = require('gulp');
+ var webpack       = require('gulp-webpack');
+ var webpackConfig = require('./webpack.config.js');
+
+ gulp.task('webpack', function() {
+   return gulp.src(config.javascript.src)
+       .pipe(webpack(webpackConfig))
+       .pipe(gulp.dest(webpackConfig.output.publicPath))
+ });

webpack(webpackConfig)メソッドで、webpackConfigの設定に従って、ビルドされます。

webpack.config.jsを作成します。
webpackの設定ファイルは、webpack.config.jsとし、webpackのビルドの設定を記載します。

// gulp/taks/webpack.config.js
+ var config = require('./config');
+
+ module.exports = {
+   // エントリファイルを記載(複数記載できます)
+   entry: {
+     application: './' + config.gulpAssets + '/javascripts/application'
+   },
+   // 出力先を記載。filenameで作成されたファイルを指定
+   output: {
+     filename:   '[name].bundle.js',
+     publicPath: config.javascript.dest
+   },
+   // 対照するファイル(extension: 拡張子を指定)
+   resolve: {
+     extensions: ['', '.js', '.jsx']
+   }
+ };

webpackのconfigのドキュメント: configuration


defaultタスクにwebpackタスクを追加します。

  // gulp/tasks/default.js
  var gulp = require('gulp');
  var runSequence = require('run-sequence');

  gulp.task('default', function() {
    runSequence(
      'clean',
*     ['compile-sass', 'compile-scss'],
+     'webpack'
    );
  });


jQueryをインストールしてみます

npm install --save jquery


そして、作成したjsファイルからjQueryを呼び込み利用してみます。

// gulp/assets/javascripts/application.js
+ var $ = require('jquery');
+ alert('jQuery version:' + $.fn.jquery);

npmでインストールしたパッケージをrequire('<パッケージ>')でインポートできるようになります。

では、gulpコマンドでビルドすると、webpackでapplication.bundle.jsが作成されたのがわかると思います。

$ gulp
[11:09:02] Using gulpfile ~/GDrive/rails/rails_with_gulp/gulpfile.js
[11:09:02] Starting 'default'...
...
[11:09:02] Starting 'webpack'...
[11:09:02] Finished 'webpack' after 219 ms
[11:09:02] Finished 'default' after 244 ms
[11:09:03] Version: webpack 1.12.9
                Asset    Size  Chunks             Chunk Names
application.bundle.js  257 kB       0  [emitted]  application


babelでES6をコンパイル

babelをインストールします。

npm install --save-dev babel babel-core babel-cli babel-loader babel-preset-es2015

webpack.config.jsbabelを追加します。

  // gulp/tasks/webpack.config.js
  var config = require('./config');

  module.exports = {
    // エントリファイルを記載(複数記載できます)
    entry: {
      application: './' + config.gulpAssets + '/javascripts/application'
    },
    // 出力先を記載。filenameで作成されたファイルを指定
    output: {
      filename:   '[name].bundle.js',
      publicPath: config.javascript.dest
    },
    // 対照するファイル(extension: 拡張子を指定)
    resolve: {
      extensions: ['', '.js', '.jsx']
*   },
+   // baelをloaderとすることでes6をjsに変換できます
+   // 他loaderによりcoffeeなどのファイルをjsに変換できます
+   module: {
+     loaders: [
+       { test: /\.js?$/, loader: "babel?presets[]=es2015" }
+     ]
+   }
  };


jsファイルをES6の記法で書きなおしてみます。

// gulp/assets/javascripts/application.js
* import $ from 'jquery';
  alert('jQuery version:' + $.fn.jquery);

+ class Hoge {
+   constructor() {
+     let a = 1;
+     console.log(`Hello es6. a is ${a}`);
+   }
+ }
+
+ new Hoge();

gulpでビルドしなおしても、問題なくbableでES6がトランスパイルされます。


ダイジェストを追加

sass/scssと同様に、jsファイル名にもダイジェストを追加します。

// gulp/webpack.js
  var config        = require('./config');
  var gulp          = require('gulp');
  var webpack       = require('gulp-webpack');
  var webpackConfig = require('./webpack.config.js');
+ var rev           = require('gulp-rev');

  gulp.task('webpack', function() {
    return gulp.src(config.javascript.src)
        .pipe(webpack(webpackConfig))
+       .pipe(rev()) // ダイジェストをファイル名につける
        .pipe(gulp.dest(webpackConfig.output.publicPath)) // jsファイルの出力先
+       .pipe(rev.manifest(config.rev.dest, config.rev.opts)) // manifestファイルの設定
+       .pipe(gulp.dest(config.publicAssets)); // manifestファイルの出力先
  });


rev.manifestの引数で適切にパスやオプションを指定しているので、cssとjsのダイジェスト値が次のようにマージされています。

// public/assets/rev-manifest.json
{
  "application.bundle.css": "application-d621e173c7.bundle.css",
  "application.bundle.js": "application-c87f2216e1.bundle.js"
}


JSファイルをミニファイ

JSファイルのミニファイには、gulp-uglifyを使用します。

npm install --save-dev gulp-uglify

uglifyでjsファイルをミニファイします。

// public/assets/javascripts/webpack.js
  var config        = require('./config');
  var gulp          = require('gulp');
  var webpack       = require('gulp-webpack');
  var webpackConfig = require('./webpack.config.js');
  var rev           = require('gulp-rev');
+ var uglify        = require('gulp-uglify');

  gulp.task('webpack', function() {
    return gulp.src(config.javascript.src)
        .pipe(webpack(webpackConfig))
+     .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest(webpackConfig.output.publicPath))
        .pipe(rev.manifest(config.rev.dest, config.rev.opts))
        .pipe(gulp.dest(config.publicAssets));
  });


gulpでビルドし、JSファイルを見ると次のようにミニファイされていることがわかると思います。

// public/assets/javascripts/application-63a661c7c2.bundle.js

!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.
...


5. 変更監視、画面リロード、通知

変更監視

ファイルの変更を監視し、変更されたらビルドが走るようにします。
gulp.watchというメソッドがデフォルトであるのでそれを利用します。

// gulp/tasks/watch.js
+ var config = require('./config');
+ var gulp   = require('gulp');
+
+ gulp.task('watch', function() {
+   gulp.watch(config.watch.stylesheetSass, ['compile-sass']);
+   gulp.watch(config.watch.stylesheetScss, ['compile-scss']);
+   gulp.watch(config.watch.javascript,     ['webpack']);
+ });

watchタスクを実行すると、jsやsass/scssファイルを変更すると自動的にビルドを行ってくれるようになります。

gulp watch


画面リロード

ファイルがビルドしたら、画面をリロードするようにします。
browser-syncをインストールします。

npm install --save-dev browser-sync

browserSyncを追加します。

// gulp/tasks/watch.js
  var config = require('./config');
  var gulp   = require('gulp');
+ var browserSync = require('browser-sync').create();

  gulp.task('watch', function() {
    browserSync.init({
      proxy: 'localhost:3000' // サーバのホスト名を記載
    });

    gulp.watch(config.watch.stylesheetSass, ['compile-sass']);
    gulp.watch(config.watch.stylesheetScss, ['compile-scss']);
    gulp.watch(config.watch.javascript,     ['webpack']);

+   // public配下のファイルが変更された場合画面をリロードする(必要に応じてwatch先を変更)
+   gulp.watch(config.watch.browserSync).on('change', browserSync.reload);
  });

こちらもgulp watchで監視し、画面がリロードされます。


通知

次のように、コンパイルが完了したら通知を出すようにしてみます。
f:id:nipe880324:20151218023734p:plain:w240

gulp-notifyをインストールします。

npm install --save-dev gulp-notify

notifyメソッドを呼ぶことで通知が表示されます。

// gulp/tasks/webpack.js
  var config        = require('./config');
  var gulp          = require('gulp');
  var webpack       = require('gulp-webpack');
  var webpackConfig = require('./webpack.config.js');
  var rev           = require('gulp-rev');
  var uglify        = require('gulp-uglify');
+ var notify        = require('gulp-notify');

  gulp.task('webpack', function() {
    return gulp.src(config.javascript.src)
        .pipe(webpack(webpackConfig))
      .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest(webpackConfig.output.publicPath))
        .pipe(rev.manifest(config.rev.dest, config.rev.opts))
*       .pipe(gulp.dest(config.publicAssets))
+       .pipe(notify('finish webpack'));
  });

sass_scss.jsにも追加します。

// gulp/tasks/sass_scss.js
  var config = require('./config');
  var gulp = require('gulp');
  var sass = require('gulp-sass');
  var rename = require('gulp-rename');
  var rev  = require('gulp-rev');
  var minifyCss = require('gulp-minify-css');
+ var notify    = require('gulp-notify');

  gulp.task('compile-sass', function() {
    return gulp.src(config.stylesheet.srcSass)
        .pipe(sass({ indentedSyntax: true, errLogToConsole: true }))
        .pipe(minifyCss())
        .pipe(rename({ suffix: '.bundle' }))
        .pipe(rev())
        .pipe(gulp.dest(config.stylesheet.dest))
        .pipe(rev.manifest(config.rev.dest, config.rev.opts))
*       .pipe(gulp.dest(config.publicAssets))
+       .pipe(notify('finish compile-sass'));
  });

  gulp.task('compile-scss', function() {
    return gulp.src(config.stylesheet.srcScss)
        .pipe(sass({ indentedSyntax: false, errLogToConsole: true }))
        .pipe(minifyCss())
        .pipe(rename({ suffix: '.bundle' }))
        .pipe(rev())
        .pipe(gulp.dest(config.stylesheet.dest))
        .pipe(rev.manifest(config.rev.dest, config.rev.opts))
*       .pipe(gulp.dest(config.publicAssets))
+       .pipe(notify('finish compile-scss'));
  });


6. Railsと統合

まずは、gulpでビルドしておきます。

index.html.erbなどの各テンプレートファイルから特定のjsやcssを読み込めるようにするために、、content_forを追加ます。

  <!-- app/views/layouts/application.html.erb -->
  <!DOCTYPE html>
  <html>
  <head>
    <title>GulpTest</title>
-   <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
-   <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
+   <%= yield :head if content_for?(:head) %>
    <%= csrf_meta_tags %>
  </head>
  <body>

  <%= yield %>

+ <%= yield :head if content_for?(:foot) %>
  </body>
  </html>


index.html.erbでjsファイルをロードするようにします。

  <!-- app/views/top/index.html.erb -->
  <h1>Top#index</h1>
  <p>Find me in app/views/top/index.html.erb</p>

+ <% content_for :head do %>
+   <%= stylesheet_link_tag gulp_asset_path('application.bundle.css') %>
+ <% end %>
+
+ <% content_for :foot do %>
+   <%= javascript_include_tag gulp_asset_path('application.bundle.js') %>
+ <% end %>

ダイジェストに対応できるためにマニフェストファイルをREV_MANIFEST定数に入れておきます。

# config/initializers/rev_manifest.rb
+ rev_manifest_path = 'public/assets/rev-manifest.json'
+
+ if File.exist?(rev_manifest_path)
+   REV_MANIFEST = JSON.parse(File.read(rev_manifest_path))
+ end

gulpで作成されたファイルへのパスを返すgulp_assets_pathヘルパーを作成します。
※少しバグがあるので適宜直してください。

# app/helpers/applicaiton_helper.rb
  module ApplicationHelper
+   def gulp_asset_path(path)
+     new_path = REV_MANIFEST[path] if defined?(REV_MANIFEST)
+     raise "path miss match error: #{path}" if new_path.blank?
+
+     return "/assets/javascripts/#{new_path}" if new_path.end_with?('.js')
+     "/assets/stylesheets/#{new_path}"        if new_path.end_with?('.css')
+   end
  end


rails serverでサーバーを起動させ、gulp watchでbrowserSyncを起動させると次のように画面が開きます。
f:id:nipe880324:20151218023652p:plain:w420


アセットファイルなどを変更すると、ビルドされ、通知が出て、画面がリロードされます。

以上です。