Gulp で複数のプロジェクトを管理する

あんまり無いと思うんですが、ひとつのリポジトリ内でそれぞれ独立した案件のディレクトリを切っているケースに遭遇しました。 そしてその中にそれぞれ Gulp が入ってる、みたいな。

こんな感じです。

template  
    gulp
    source
project1  
    gulp
    source
project2  
    gulp
    source
project3  
    gulp
    source

で、みんな同じ Gulp task を保有しており、案件が発生する度に template のファイルを copy してそこから拡張していきます。 node_modules とかも全部それぞれのディレクトリ内で管理されてしまっているので、リポジトリが無駄に肥大化& init がめんどくさい。

ので、Gulp を外に出して npm scripts を実行する際に option を指定することでそれぞれのディレクトリを包括的に管理できるようにしてみます。

まず、packege.json 内に name と config を設定しておきます。

{
  "name": "app",
  "config": {
    "issue": "notset"
  },
  "scripts": {
    "start": "gulp"
  }
}

その後、env.js という scripts を作って、その中で issue に設定された値を引っ張ります。 ※ES6です

import minimist from 'minimist';

// issue option
const issueOptions = {  
  string: 'issue',
  default: { issue: process.env.npm_package_config_issue || 'notset' }
};

const issueOption = minimist(process.argv.slice(2), issueOptions);  
let isSetedIssue = false;

if(issueOption.issue != 'notset'){  
  isSetedIssue = true;
}

// export isProduction
export default {  
  issue: issueOption.issue,
  isSetedIssue: isSetedIssue
}

issueOptions 内の process.env.npm_package_config_issue で packege.json の config に設定した値を引っ張ってこれます。 これで、task 用の scripts 内で、この scripts を import すれば、オプションで指定したディレクトリのパスと ディレクトリがきちんと設定されているかが取得できるようになります。

こんな感じです。

import gulp from 'gulp';  
import gutil from 'gulp-util';  
import runSequence from 'run-sequence';

// env.js を import
import env from 'env';

gulp.task('default', () => {  
  // issue がセットされてなかったらタスクを実行せずに警告を出す
  if(!env.isSetedIssue){
    gutil.log('[issue]', gutil.colors.red('plese set issue'));
  }
  else {
    runSequence('clearCache', 'cleanBuild', ['copyFile', 'image:sprite'], ['slim', 'sass', 'browserify', 'image:min']);
  }
});

env.isSetedIssue でディレクトリが指定されているのかの確認、env.issue で指定されたディレクトリのパスが取れるようになりました。 パスを指定するタスクを実行する際に、env.issue を結合しておけば、指定したディレクトリのパスになりますね。

そしたら後は、npm start など、scripts を実行する際に以下のコマンドを一度実行するだけ!

npm start --app:issue=project名  

これで Gulp をディレクトリ毎に作らなくてよくなります😊

ちなみに、ぼくは npm config set issue:progect名 みたいな設定方法しか知らなかったのですが、Twitter で package名を指定すれば同時にできるのを教えていただきました!

いつだって救いは Twitter にある。 教えていただいた方、ありがとうございます!