gulp-symを使って特定のファイルをシンボリックしてみた

完全に運用フローの中で考えた案になります。

Gulpを使って普段はコーディングをしています。（HTMLテンプレートも使っていたり）
新規の場合は自由に吐き出して納品すればOKなんですが、例えばコンテンツコーディングの時に使えるかもしれないと思ったのでTipsとして残しておきます。

サンプルコードは、簡易版になります。サイトにあった調整は必要になるかもしれません。

# どんな時に使う？

* 既存のサイトがすでに公開されていて、コンテンツだけをコーディングする時（LPなど）
* 既存の部品を使いつつコーディングしなければいけない時（例えばすでにSSIなどを使用している等）
* 既存の部品はGitで管理したくない（管理ファイルが多くなるため）
* 更新作業など頻繁にコンテンツコーディングしなければいけない時
* 動画埋め込み・Webfontなどの重たいデータをGitで管理したくない

## プロジェクトのディレクトリイメージ

ディレクトリのイメージは以下のような形になります。普通はこういったような状態にはならない？かもしれませんが。。。

![イメージマップ.png](https://qiita-image-store.s3.amazonaws.com/0/34020/ac41027b-a678-02b6-943d-29f48eef5271.png)

用途は様々ですが、今までは必要なファイルを編集ディレクトリに置いてCopyタスクで処理させてやっていました。しかし、実用的じゃないし毎回プロジェクトごとに既存ファイルを配置するとローカルストレージを圧迫するなーっと個人的に悩んでいました。

# gulp-symとvinyl-fsを使う

使用するライブラリは、[gulp-sym](https://github.com/soyuka/gulp-sym)と[vinyl-fs](https://github.com/gulpjs/vinyl-fs)を使います。

gulpの4系だと[gulp.symlink](https://gulp.readme.io/docs/gulpsymlinkfolder-options)というAPIが追加されているので4系になったら、このTipsも古くなってしまいますが。。。※メモとして

既存の部品をプロジェクト配下以外のローカルディレクトリに配備させる。
Gulpfileにタスクを書いています。

サンプルコードのため、以下のタスクで作っています。
※テンプレートエンジンやSassなどのタスクは割愛

* BrowserSync（SSIを表示できるようにしておく）
* 既存ファイルのシンボリックが生成される

## インストールコマンド

```
$ npm init
$ npm install browser-sync --save-dev
$ npm install vinyl-fs --save-dev
$ npm install gulp-sym --save-dev
```

Vinylの役割がよくわかっていなかったので、日本語の記事に書いていることを引用させていただきます。[Gulp = Vinyl + Stream + Orchestrato](http://qiita.com/eielh/items/d5e10d5f05df60621d15)

> Vinylはファイルを抽象化したライブラリらしいです。
> そのローカルファイルシステム用のアダプタであるvinyl-fsというライブラリがgulpのAPIを提供しています。


# ファイル構成

以下のファイル構成になります。※HTMLテンプレートエンジンなど使う場合は、編集ファイルと吐き出しファイルのが一般的かと思います。

```
・/Users/ユーザ名/管理したいディレクトリ/assets
 - header.html
 - footer.html
・/Users/ユーザ名/プロジェクトディレクトリ（作業するディレクトリ）
 - .git
 - .gitignore
 - build（HTMLを管理・シンボリックが生成されるディレクトリ・BrowserSyncのドキュメントルート）
 - gulpfile.js
 - symlink_config.js（既存部品までのパスが記述されているファイル：各自で管理する部分）
 - node_modules
 - package.json

~~ more（既存サイトのプロジェクトが増えてきたら同じ設定を繰り返す） ~~
```

## .gitignoreの設定

gitの除外ファイルは以下のようにしておきます。
symlink_config.jsは、各自で管理させる必要があります。（ユーザごとに既存部品の格納場所が異なるため）

```
symlink_config.js
node_modules
.AppleDouble
.DS_Store
```

## 既存の部品を配置

既存の部品（画像やHTML等）を任意のディレクトリに配置させる
symlink_config.jsを作成する

```js
module.exports = {
  commonPath : '/Users/ユーザ名/配置させた任意のディレクトリ/assets/**.html'
};
```

# gulpfile.jsを記述

簡易版のgulpfile.jsは以下になります。
実案件で使う場合は、調整は必要になります。

```js
'use strict';

var gulp = require('gulp');
var browserSync = require("browser-sync");
var symlink = require('gulp-sym');
var ssi = require('browsersync-ssi');
var vfs = require('vinyl-fs');
var symlink_config = require('./symlink_config'); //各自のローカルストレージのパスが記述します。（.gitignoreでファイルは除外させる）

// シンボリックリンクが生成させるためのタスク
gulp.task('symlink', function () {
  return vfs.src(symlink_config.commonPath, {followSymlinks: false})
  .pipe(vfs.symlink('build/assets'));
});

// browserSyncの立ち上げタスク
gulp.task("browserSyncTask", function () {
  browserSync({
    server: {
      baseDir: "./build", // ルートとなるディレクトリを指定
      middleware: [
      ssi({
        baseDir: __dirname + "/build",
        ext: ".html"
      })
    ]}
  });
  // buildフォルダ以下のファイルを監視
  gulp.watch("build/**", function() {
    browserSync.reload();   // ファイルに変更があれば同期しているブラウザをリロード
  });
});
```

# 参考記事

* [vinyl-fs](https://github.com/gulpjs/vinyl-fs)
* [gulp-sym](https://github.com/soyuka/gulp-sym)
* [Gulp = Vinyl + Stream + Orchestrator](http://qiita.com/eielh/items/d5e10d5f05df60621d15)
* [gulp.symlink](https://gulp.readme.io/docs/gulpsymlinkfolder-options)
* [gulp4.0 migration guide](http://qiita.com/joe-re/items/e04010ed03826fb94a16)
* [node_modules をシンボリックリンクで管理する](http://bunlog.d-s-b.jp/2014/06/09/managed-node_modules-directory/)