gulpでwiredepを使ってbowerのライブラリを読み込む

/

wiredep

wiredepはbowerでダウンロードしたライブラリのリンクを依存関係を考慮してソースファイルにを埋め込んでくれるライブラリです。
gulpの一連の処理の中でライブラリの読み込みを自動化したいのでタスクのスクリプトを書いていきます。

wiredep/Github
Bowerでフロントエンド向けライブラリ管理する/koltatt
gulpを使ったフロントエンド開発 導入編/koltatt

準備

bower

まずソースで読み込むライブラリが必要なのでbowerでインストールしていきますが、wiredepは挿入するライブラリをbower.jsonのdependenciesを見て判断するのでbower.jsonを作成してからライブラリをインストールします。

//bower.jsonの作成
$ bower init
...
$ bower install --save jquery

gulp

wiredepのインストール

$ npm install wiredep --save-dev

gulpfileの作成

vi gulpfile.js
var gulp         = require('gulp');
var wiredep      = require('wiredep').stream;

gulp.task('wiredep', function () {
  gulp.src('./src/index.html')
    .pipe(wiredep())
    .pipe(gulp.dest('./dist'));
});

wiredepとgulp-wiredepのどちらを使うか

gulpでは元々はgulp向けではなく独自に作られたライブラリを使う場合にgulp用にカスタマイズされたgulp-[ libary ]という名前のパッケージを使うケースが良くあります。
wiredepにもgulp-wiredepというパッケージがあるのですがwiredepの場合

var wiredep = require('wiredep').stream;

という風にstreamを着けて読みこめば本家のwiredepがgulpで問題なく利用できるため、gulp用にカスタマイズされたgulp-wiredepをわざわざ使う人はあまりいないようです。更新頻度も本家のほうが活発なので特別な理由がない限りは元々のwiredepを使うのが良いと思います。

HTML

HTMLでbowerのライブラリを読み込むために、cssとjavascirptをそれぞれ挿入したい位置にプレースホルダーを記入します。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <!-- bower:css -->
    <!-- endbower -->
    <link rel="stylesheet" href="src/css/style.css">
  </head>
  <body>
    <!-- bower:js -->
    <!-- endbower -->
  </body>
</html>

実行

準備が済んだのでgulpを実行します。

$ gulp wiredep
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <!-- bower:css -->
    <!-- endbower -->
    <link rel="stylesheet" href="src/css/style.css">
  </head>
  <body>
    <!-- bower:js -->
    <script src="../bower_components/jquery/dist/jquery.js"></script>
    <!-- endbower -->
  </body>
</html>

出力先のHTMLを確認するとjQueryへのリンクが挿入されています。

bower.json

ライブラリ内のどのファイルへのリンクを埋め込むかはbower.jsonの各ライブラリのmainの項目で指定されます。
jQueryのbower.jsonを確認してみると

{
  "name": "jquery",
  "main": "dist/jquery.js",
  ...
}

となっているのため先ほどのタスクではdist/jquery.jsがHTMLに挿入されました。
読み込むファイルはの対象を変更・追加したい時にはプロジェクトのbower.jsonで各ライブラリの値をoverrideで上書きします。

{
  ...
  "dependencies": {
    "jquery": "^3.1.1"
  },
  "overrides": {
    "jquery": {
      "main": "dist/jquery.min.js"
    }
  }
}

mainの値をオーバーライドしてからタスク実行すると新たに指定したファイルが読み込まれます。

$ gulp wiredep
<!-- bower:js -->
<script src="../bower_components/jquery/dist/jquery.min.js"></script>
<!-- endbower -->

読み込ませたいファイルが複数ある場合はリストで指定します。

$ bower install -save bootstarp
{
  ...
  "overrides": {
    "jquery": {
      "main": "dist/jquery.min.js"
    },
    "bootstrap": {
      "main": [
        "dist/css/bootstrap.min.css",
        "dist/js/bootstrap.min.js"
      ]
    }
  }
}
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <!-- bower:css -->
    <link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css" />
    <!-- endbower -->
    <link rel="stylesheet" href="dist/css/style.css">
  </head>
  <body>
    <h1>gulp project</h1>
    <!-- bower:js -->
    <script src="../bower_components/jquery/dist/jquery.min.js"></script>
    <script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- endbower -->
  </body>
</html>

SCSSを埋め込む

wiredepではHTML以外にもライブラリのリンクを埋め込む事が出来ます。

$ bower install --save bootstrap-sass gulp-sass
var gulp         = require('gulp');
var wiredep      = require('wiredep').stream;

gulp.task('wiredep:style', function () {
  gulp.src('./src/sass/style.scss')
    .pipe(wiredep())
    .pipe(gulp.dest('./dist/sass/'));
});
// bower:scss 
// endbower
{
  ...
  "dependencies": {
    "bootstrap-sass": "^3.3.7"
  },
  "overrides": {
    "bootstrap-sass": {
      "main": [
        "assets/stylesheets/_bootstrap.scss",
        "assets/javascripts/bootstrap.js"
      ]
    }
  }
}
$ gulp wiredep:style
// bower:scss
@import "../../bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss";
// endbower

一連の処理の自動化

SCSSからライブラリが読み込めるようになったので、先程のgulpfileを書き換えてgulpで一連の処理を自動化出来るようにします。

{
  ...
  "dependencies": {
    "jquery": "^3.1.1",
    "bootstrap-sass": "^3.3.7"
  },
  "overrides": {
    "jquery": {
      "main": "dist/jquery.min.js"
    },
    "bootstrap-sass": {
      "main": [
        "assets/stylesheets/_bootstrap.min.scss",
        "assets/javascripts/bootstrap.min.js"
      ]
    }
  }
}
var gulp         = require('gulp');
var sass         = require('gulp-sass');
var wiredep      = require('wiredep').stream;

gulp.task('wiredep', function () {
  gulp.src('./src/index.html')
    .pipe(wiredep())
    .pipe(gulp.dest('./dist/'));
});

gulp.task('wiredep:sass', function () {
  gulp.src('./src/sass/style.scss')
    .pipe(wiredep())
    .pipe(gulp.dest('./dist/sass/'));
});

gulp.task('style',['wiredep:sass'], function () {
  gulp.src('./dist/sass/style.scss')
  .pipe(sass())
  .pipe(gulp.dest('./dist/css/'));
});

gulp.task('default', ['wiredep'], function () {
  gulp.start('style');
});
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <!-- bower:css -->
    <!-- endbower -->
    <link rel="stylesheet" href="./css/style.css">
  </head>
  <body>
    <!-- bower:js -->
    <!-- endbower -->
  </body>
</html>
// gulp defaultの実行
$ gulp
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <!-- bower:css -->
    <!-- endbower -->
    <link rel="stylesheet" href="dist/css/style.css">
  </head>
  <body>
    <!-- bower:js -->
    <script src="../bower_components/jquery/dist/jquery.min.js"></script>
    <script src="../bower_components/bootstrap-sass/assets/javascripts/bootstrap.min.js"></script>
    <!-- endbower -->
  </body>
</html>

wiredepでdist/sass/style.scssにbootstrap.scssを読み込んだあとstyle.scssをcssにコンパイルしているので、bootstrapを利用したしたスタイルシートをscssで書くことが出来ます。

あとがき

bowerでライブラリをインストールするのは便利なのですがライブラリが丸ごとインストールされるので、そのままプロジェクトに組み込むと各ライブラリ毎にあるbower.jsonや使わないファイルまで追加されてしまいプロジェクト全体が肥大化して可読性がも下がります。
wiredepを使えば必要ファイルを自動的にソースの好きな位置に組み込めるので、gulpのcopyタスクと組み合わせてプロジェクトをダウンサイジングさせる事が出来ます。