【初心者】Gulp記述メモ【備忘録】

# はじめに
投稿時点で、筆者は知識ゼロの状態から勉強を初めて2ヶ月程度の実力です。
そのため、理解不足や説明不足、誤った内容や呼び方をしている可能性があります。
万が一参考にする場合は上記の点を考慮した上でご一読ください。
説明文の内容はChatGPT先生からの引用が多いです。

### Gulp 3以前[task()メソッドによるタスク定義]（公式非推奨、使用は可能）
```javascript:gulpfile.js
const gulp = require("gulp");

gulp.task('sass',  () => {
  return (
    gulp
      .src("src/sass/style.scss")
      .pipe(
        sass({
          outputStyle: "expanded"
        })
      )
      .pipe(gulp.dest("./dist"))
  );
});
```

### Gulp 4以降[タスク関数（関数を使用してタスクを定義）での記述]（公式推奨）
#### 通常の関数宣言での記述
```javascript:gulpfile.js
const gulp = require("gulp");

function compileSass() {
  return (
    gulp
      .src("src/sass/style.scss")
      .pipe(
        sass({
          outputStyle: "expanded"
        })
      )
      .pipe(gulp.dest("./dist"))
  );
};

exports.sass = compileSass;
```

#### アロー関数
```javascript:gulpfile.js
const gulp = require("gulp");

const compileSass = () => {
  return (
    gulp
      .src("src/sass/style.scss")
      .pipe(
        sass({
          outputStyle: "expanded"
        })
      )
      .pipe(gulp.dest("./dist"))
  );
};

exports.sass = compileSass;
```


#### gulpパッケージインストール部分の記述変更
```javascript:gulpfile.js
const { src, dest } = require("gulp");

const compileSass = () => {
  return (
    src("src/sass/style.scss")
      .pipe(
        sass({
          outputStyle: "expanded"
        })
      )
      .pipe(dest("./dist"))
  );
};

exports.sass = compileSass;
```
`const { src, dest } = require("gulp");`と記述した場合、gulpパッケージからsrcとdestを取り出しているので`src()`や`dest()`を呼び出すときに`gulp.src()`や`gulp.dest()`のようにgulpオブジェクトを呼び出す必要がない。
新たに必要な要素がある場合は記述を変更する必要あり。
例：`const { src, dest, watch } = require("gulp");`



- **`const gulp = require("gulp");`の特徴**
    - メリット
gulp モジュールのすべての機能にアクセスできることです。gulp モジュールには、ファイルのコピー、圧縮、SassやTypeScriptなどのコンパイルなどの機能が含まれています。この場合、タスクの中で必要なすべての機能を使用することができます。

    - デメリット
gulp モジュール全体をインポートしているため、必要のない機能も含まれてしまうことです。また、複数のプラグインを使用する場合、変数名が重複する可能性があるため、名前空間の競合を避けるために変数名を変更する必要がある場合があります。

- `const { src, dest } = require("gulp");`の特徴
    - メリット
必要な機能のみをインポートできることです。この場合、src()やdest()などの関数のみを使用することができ、不要な機能を含める必要がありません。

   - デメリット
必要な機能を全て列挙する必要があるため、必要な関数が多い場合には長くなり、コードの可読性が低下する可能性があることです。また、プラグインのアップデートや変更によっては、必要な関数が変更される可能性があるため、定期的にコードを確認して更新する必要があります。


`const gulp = require("gulp");` は、gulp モジュールを gulp 変数に代入して読み込む方法で、一般的には「単一バインド」と呼ばれます。
`const { src, dest } = require("gulp");` は、gulp モジュールから src と dest という2つの関数をインポートする方法で、一般的には「分割代入」と呼ばれます。

- 単一バインド

    - メリット
シンプルで直感的なコードを書くことができる。
変数名の競合を避けることができる。

    - デメリット
読み込んでいない機能が含まれる可能性がある。
変数名の競合を避けるために変数名を変更する必要がある場合がある。

- 分割代入

    - メリット
必要な機能だけを読み込むことができるため、不必要な機能を含めないシンプルなコードを書くことができる。
読み込んだ機能を直接変数名で参照できるため、コードの可読性が向上する。

    - デメリット
読み込んだ機能が多い場合、コードが冗長になる可能性がある。
変数名の変更によっては、複数の箇所を修正する必要がある場合がある。
これらのメリットとデメリットを考慮して、どちらの方法を採用するかは、プロジェクトの規模やチームのスタイルによって異なる場合があります。一般的には、必要な機能を限定するために分割代入がよく使用されますが、プロジェクトによっては単一バインドが好まれる場合もあります。




#### return文をコールバック関数に変更
```javascript:gulpfile.js
const { src, dest } = require("gulp");

const compileSass = (done) => {
  src("src/sass/style.scss")
    .pipe(
      sass({
        outputStyle: "expanded"
      })
    )
    .pipe(dest("./dist"))
    done();
};

exports.sass = compileSass;
```
gulpでは、タスクの完了を通知するために、return文またはコールバック関数のどちらを使用しても問題ありません。
この done という引数は、Gulpタスクが完了したことを通知するために使用されるコールバック関数です。このコールバック関数はGulpタスクの実行中に呼び出され、タスクが完了したことを示すために呼び出します。
このコールバック関数は、Gulpタスクが非同期である場合に必要であり、タスクの完了時に呼び出されることを示すために使用されます。これは、タスクの完了前にGulpが次のタスクを実行することを許可することを可能にします。
このコールバック関数は、任意の名前で定義することができますが、通常は done と呼ばれます。このコールバック関数がない場合、Gulpはタスクが完了するまで待機し続け、次のタスクを実行できません。

Gulpタスクは全て非同期タスクなのでどちらかが必要となる。

Gulpタスクはすべて非同期タスクです。Gulpは、ストリームを使用してファイルを処理するため、タスクは非同期的に処理されます。各タスクは、ファイルをストリームで読み取り、パイプラインで変換を行い、最終的にストリームで書き出すため、各タスクは非同期的に実行されます。このため、Gulpタスクは必ずしも順序通りに実行されない場合があります。タスクを同期的に実行するには、gulp.series または gulp.parallel を使用して、タスクをシリーズまたは並列に実行することができます。

- return 文
    - メリット
関数の戻り値として、実行結果を返すことができます。
return 文が呼び出された時点で、処理が完了するため、コードが簡潔になります。

    - デメリット
処理が完了するまで、処理が戻らないため、非同期処理には向いていません。
複雑な処理を実行する場合、コードが冗長になることがあります。

- コールバック関数
    - メリット
処理が完了した時点で、コールバック関数が呼び出されるため、非同期処理に向いています。
コールバック関数がパラメーターとして渡されるため、複雑な処理をシンプルに表現することができます。

    - デメリット
コードが冗長になることがあります。
コールバック関数を連鎖させることによって、コールバック地獄に陥ることがあります。
一般的には、処理が非同期的である場合は、コールバック関数を使用することが推奨されます。ただし、非同期処理ではない場合は、return 文を使用することができます。また、コールバック関数を使用する場合は、コードが冗長になることを避けるために、Promise や async/await を使用することができます。


#### 役に立つかわからない情報
```javascript:gulpfile.js
const gulp = require("gulp");

const compileSass = () =>
  gulp.src("src/sass/style.scss")
    .pipe(sass({ outputStyle: "expanded" }))
    .pipe(gulp.dest("./dist"));

exports.sass = compileSass;
```
`const compileSass = () =>`の後に{}が続く場合、アロー関数の本来の書き方から外れます。アロー関数は、単一の式を返す場合は{}を省略できますが、複数の文を含む場合は{}で囲む必要があります。そのため、{}を省略する場合は、上記のように書くことができます。
このように書くことで、短くシンプルにコードを書くことができます。

しかしGulpタスクは全て非同期タスクなのでGulpがタスクが完了したことを確認し、次のタスクを実行するために必ずreturn文かコールバック関数でが必要になるはず…。


### 参考リンク
[必ず使うタスクランナーGulpとGruntの基本コード9選](https://ics.media/entry/9199/)
[絶対つまずかないGulp 4入門 インストールとSassを使うまでの手順](https://ics.media/entry/3290/)
[Gulp4 + Webpackの超オススメ設定を公開【爆速コーディング環境構築】](https://flex-box.net/gulp-webpack/)
↑　もっと読んだほうが良い、参考リンクも充実しており自分にあってる。
[Gulp4の変更点と新しい書き方](https://qiita.com/manabuyasuda/items/0971dbd3729cf68f87fb)