gulp 4 で複数の gulpfile.js にあるタスクを1つのファイルで実行する方法

はじめに

1つのプロジェクトで複数のサイトがある場合などに、それぞれのタスクを1つの gulpfile.js で書くとファイルが肥大化したりします。

そこで、サイトごとに gulpfile をつくり、それを1つの gulpfile から呼び出す方法を考えました。今日は実際に作った gulpfile.js のコードと併せて、そのアイディアをご紹介します。

今回は単に gulpfile を分割するのではなく、サイト毎の gulpfile でも npx gulp できるように実装しています。

gulp
4.0.2
gulp-sass
4.0.2
node-sass
4.13.0
Node.js
10.16.9
OS
Win 10 Home
目次
  1. ファイル構成
  2. 実装したコード
  3. ポイントと注意点

1. ファイル構成

今回は下記のようなファイル構成にしています。

ネットショップを想定し、admin が管理画面、shop がショップ画面のディレクトリです。
それぞれに gulpfile.js があり、タスクは scss コンパイルで試しました。

my-shop/
│
├ admin/
│ ├ css/
│ ├ scss/
│ │ └ style.scss
│ └ gulpfile.js
│
├ node_modules/
│
├ shop/
│ ├ css/
│ ├ scss/
│ │ └ style.scss
│ └ gulpfile.js
│
├ gulpfile.js
├ package-lock.json
└ package.json

gulp の実行に必要なライブラリはすべてインストール済とします。

> cd /path/to/my-shop
> npm init
> npm i gulp gulp-sass node-sass

2. 実装したコード

各 gulpfile.js を下記のように書きます。

/admin/gulpfile.js
const { dest, src, task, watch } = require("gulp");
const gulpSass = require("gulp-sass");

let dirName = ".";
const cssDir = "/css";
const scssFiles = "/scss/*.scss";

task("admin-sass", () => {
  return src(dirName + scssFiles)
    .pipe(
      gulpSass({outputStyle: "compressed"})
        .on("error", gulpSass.logError)
    )
    .pipe(
      dest(dirName + cssDir)
    );
});

exports.default = (dir) => {
  if (typeof(dir) === "string") {
    dirName = dir;
  }
  watch(dirName + scssFiles, task("admin-sass"));
}
/shop/gulpfile.js
// admin/gulpfile.js との違いは task 名が、admin-sass から shop-sass になっているだけです

const { dest, src, task, watch } = require("gulp");
const gulpSass = require("gulp-sass");

let dirName = ".";
const cssDir = "/css";
const scssFiles = "/scss/*.scss";

task("shop-sass", () => {
  return src(dirName + scssFiles)
    .pipe(
      gulpSass({outputStyle: "compressed"})
        .on("error", gulpSass.logError)
    )
    .pipe(
      dest(dirName + cssDir)
    );
});

exports.default = (dir) => {
  if (typeof(dir) === "string") {
    dirName = dir;
  }
  watch(dirName + scssFiles, task("shop-sass"));
}
/gulpfile.js
const adminDir = "./admin";
const adminGulp = require(`${adminDir}/gulpfile`);

const shopDir = "./shop";
const shopGulp = require(`${shopDir}/gulpfile`);

exports.default = () => {
  adminGulp.default(adminDir);
  shopGulp.default(shopDir);
};

これで、my-project/ の中で npx gulp をすると、admin と shop 両方のタスクが実行されます。

> cd /path/to/my-shop/
> npx gulp

また、下記のように admin と shop のディレクトリのなかで、それぞれのタスクだけを実行させることも可能です

> cd /path/to/my-shop/admin
> npx gulp

> cd /path/to/my-shop/shop
> npx gulp

3. ポイントと注意点

実装のポイントは、admin と shop の gulpfile.js にある exports.default の引数にディレクトリ名を渡しているところです。

src() や dest()、そして watch() には、実行中の gulpfile.js を基準にした相対パスを指定します。

例えば my-shop/ の中で npx gulp をする場合は ./admin/scss/*.scss
my-shop/admin/ の中で実行する場合は ./scss/*.scss を指定しなければいけません。

そこで admin と shop の gulpfile にある default に、引数でディレクトリ名を渡すようにしました。

最後に注意点として、task の名称 "admin-sass" と "shop-sass" は重複しないようにする必要があります。どちらも同じ "sass" などで実装すると正常に動作しないのでご注意ください。