【初心者】Gulpでベンダープレフィックス自動付与（Autoprefixer）メモ【備忘録】

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


# 目的

こちらは、前回からの続きになります。
前回：[【初心者】gulpfile.js内の記述をECMAScript Modules（ESM）構文へ移行メモ【備忘録】](https://qiita.com/miyaayim_study/items/b3d0c6a28e93ab655534)

GulpのSassコンパイル後に、ベンダープレフィックスを自動で付与させてからスタイルシートを生成するのが目的です。

# 1.インストール
今回はPostCSSのプラグインの1つであるAutoprefixerを使用したいと思います。
これを使用するにはPostCSSとAutoprefixerの両方をインストールする必要があります。
下記を入力して実行してインストールします。
```
npm i -D gulp-postcss autoprefixer
```

# 2.Autoprefixer単体で動かしてみる
gulpfileにAutoprefixerを使うための記述をします。
前回からファイル内はすべてESM構文で記述していますので、今回もESM構文で記述します。
ひとまず、Sassコンパイルには組み込まずにAutoprefixer単体で動かしてみたいと思います。
```javascript:gulpfile.mjs
// Autoprefixer（ベンダープレフィックス自動付与）関連---------------------------------------------
import postcss from 'gulp-postcss'; // gulp-postcssパッケージをインポートする
import autoprefixer from 'autoprefixer'; // Autoprefixerのパッケージをインポートする

const prefixer = (done) => { // prefixerというgulpタスクを定義する

  gulp.src('./dist/style.css') // ベンダープレフィックス付与するファイルを指定
    .pipe(postcss([ // PostCSSを実行する
      autoprefixer({ // PostCSSのAutoprefixerプラグインを実行する

        // Autoprefixerのオプションを設定する
        browsers: [
          "last 2 versions", // 最新の2つのバージョン
          "ie >= 11", // Internet Explorer 11以上
          "Android >= 4" // Android 4以上
        ],

      cascade: false // CSSのプロパティを整形しない（false）で設定
      })
    ]))
    .pipe(gulp.dest("preTest")); // 出力先ディレクトリを指定する
    done();
};

export { prefixer };
```

今回お試しとして、`preTest`という新しいフォルダ内にベンダープレフィックスを付与したファイルを生成することにします。
他の細かい説明は省きます、知りたいかたは最後にある参考リンクからお調べください。
では、下記を入力して実行してみます。
```
npx gulp prefixer    
```

実行した際に、このように赤いメッセージが表示され、最後にタスクが完了したことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310435/5c256322-a0bc-b20f-8d35-62bd0f2ed7ed.png)



では、赤いメッセージは後回しにして、実際にベンダープレフィックスが付与されているか確認したいと思います。

ベンダープレフィックス付与前
```css:style.css
div {
  background-color: paleturquoise;
  padding: 1rem;
}
div h1 {
  color: red;
  backdrop-filter: grayscale(100%);
  height: 5rem;
  width: auto;
  transition: background-color 0.3s, color 0.3s;
}
div h1:hover {
  background-color: #008CBA;
  color: white;
}
div p {
  color: blue;
}
```

ベンダープレフィックス付与後
```css:style.css
div {
  background-color: paleturquoise;
  padding: 1rem;
}
div h1 {
  color: red;
  -webkit-backdrop-filter: grayscale(100%);
          backdrop-filter: grayscale(100%);
  height: 5rem;
  width: auto;
  -webkit-transition: background-color 0.3s, color 0.3s;
  transition: background-color 0.3s, color 0.3s;
}
div h1:hover {
  background-color: #008CBA;
  color: white;
}
div p {
  color: blue;
}
```

無事、成功していました。
では、赤いメッセージについてですが、ChatGPT先生に翻訳してもらいました。
>このコマンドの実行結果は、gulpタスクを実行した際にAutoprefixerのブラウザオプションの設定方法に関する警告メッセージが表示されたことを示しています。
メッセージの内容は、Autoprefixerのブラウザオプションを使用することはエラーを引き起こす可能性があるため、代わりにBrowserslist設定を使用するように推奨されていることです。具体的には、プロジェクトのpackage.jsonファイルまたは.browserslistrcファイル内にbrowserslistキーを定義することで、Browserslist設定を使用できます。
もし本当にオプションを使用する必要がある場合は、overrideBrowserslistという名前に変更することが推奨されています。
メッセージには、Browserslistに関する詳細な情報が含まれており、さらに学習するためのリンクも提供されています。

とあり、タスク内にブラウザオプションを記載せずに、ブラウザオプションは別のところに記載してほしいそうです。

これを解決するには2パターンあります。

1.`package.json`に記述する
2.`.browserslistrc`というファイルを作成し、プロジェクトルートに配置して、そのファイル内に記述する。

まずは前者のやり方を行ってみます。
`package.json`にさきほどのタスク内にあった記述を引っ越します。
`package.json`内に下記を記述しました。
```javascript:package.json
"browserslist": [
    "last 2 versions", 
    "ie >= 11", 
    "Android >= 4"
  ]
```

`package.json`内の全体はこうなりました。
```javascript:package.json
{
  "name": "project_react",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.21.4",
    "@babel/preset-env": "^7.21.4",
    "@babel/preset-react": "^7.18.6",
    "autoprefixer": "^10.4.14",
    "babel-loader": "^9.1.2",
    "browser-sync": "^2.29.1",
    "gulp": "^4.0.2",
    "gulp-imagemin": "^8.0.0",
    "gulp-postcss": "^9.0.1",
    "gulp-sass": "^5.1.0",
    "sass": "^1.61.0",
    "webpack": "^5.78.0",
    "webpack-cli": "^5.0.1",
    "webpack-stream": "^7.0.0"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "browserslist": [
    "last 2 versions", 
    "ie >= 11", 
    "Android >= 4"
  ]
}

```

`gulpfile`内の記述から、引っ越したブラウザオプションの記述を削除します。。

```javascript:gulpfile.mjs
// Autoprefixer（ベンダープレフィックス自動付与）関連---------------------------------------------
import postcss from 'gulp-postcss'; // gulp-postcssパッケージをインポートする
import autoprefixer from 'autoprefixer'; // Autoprefixerのパッケージをインポートする

const prefixer = (done) => { // prefixerというgulpタスクを定義する

  gulp.src('./dist/style.css') // ベンダープレフィックス付与するファイルを指定
    .pipe(postcss([ // PostCSSを実行する
      autoprefixer({ // PostCSSのAutoprefixerプラグインを実行する

        // Autoprefixerのオプションを設定する
        browsers: [
          "last 2 versions", // 最新の2つのバージョン
          "ie >= 11", // Internet Explorer 11以上
          "Android >= 4" // Android 4以上
        ],

        cascade: false // CSSのプロパティを整形しない（false）で設定
      })
    ]))
    .pipe(gulp.dest("preTest")); // 出力先ディレクトリを指定する
    done();
};

export { prefixer };
```

この状態で実行した結果、先程の赤いメッセージが表示されなくなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310435/56986d77-a920-7d3a-afa2-9d056bbdace3.png)

ではもう一つのパターンを試します、今から行うのは下記のやり方です。
`.browserslistrc`というファイルを作成し、プロジェクトルートに配置して、そのファイル内に記述する。

まず、先程追記した`package.json`内の記述を削除し、`package.json`内を元の状態に戻します。
`package.json`と同じディレクトリに`.browserslistrc`というファイルを作成し、ファイル内に下記を記述。
```:.browserslistrc
last 1 versions
> 5%
iOS >= 9.0
Android >= 4.1
```

これでもう一度実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310435/dfcf5c3c-5321-ce5d-57fd-291733ca7061.png)
先ほどと同じようにタスクが完了しました。
問題なさそうですね、どちらの手段をとるかはお好みでどうぞ。
私は`.browserslistrc`ファイルに記述するやり方を選びました。
理由としては、役割分担をするほうが管理しやすそうで好きだからです。

# 3.Sassコンパイルに組み込んで動かしてみる

単体で動かすやり方はわかりましたが、今度はSassコンパイルのタスクに組み込んでみます。
先程までの`prefixer`タスクは不要ですので削除してかまいません。

Sassタスクに組み込んだ結果が下記になります。
```javascript:gulpfile.mjs
// Sass関連---------------------------------------------
import gulpSass from "gulp-sass";
import sassCompiler from "sass";
const sass = gulpSass(sassCompiler);

// Autoprefixer（ベンダープレフィックス自動付与）関連
import postcss from 'gulp-postcss'; // gulp-postcssパッケージをインポートする
import autoprefixer from 'autoprefixer'; // Autoprefixerのパッケージをインポートする

const compileSass = (done) => {

  const option = [autoprefixer()]; // 定数optionにautoprefixerを指定して定義
  gulp.src("src/sass/style.scss")
    .pipe(
      sass({
        outputStyle: "expanded"
      })
    )
    .pipe(postcss(option)) // PostCSSのAutoprefixerプラグインを実行（ベンダープレフィックス自動付与）
    .pipe(gulp.dest("./dist"))
    done();
};

export { compileSass };
```

コメントアウトの説明がある部分が、追加した行になります。
注意点としては、Autoprefixerの実行は、Sassコンパイル後に実行するようにすることです。
では、Sassコンパイルを実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310435/a107acde-ecff-79b6-8975-b51749f916d2.png)

Sassコンパイルされ、生成された`style.css`を確認したところ、きちんとベンダープレフィックスが付与されていました。

以上です。

次回：[【初心者】Gulpで構文チェック（gulp-htmlhint、stylelint、ESLint）メモ【備忘録】](https://qiita.com/miyaayim_study/items/8af5f662338b2e3236aa)

# 参考サイト
[【CSS】そうだ Autoprefixerで 自動ベンプレ付けよう（Gulpで動かす）](https://www.i-ryo.com/entry/2020/02/16/110719)
[GULPでautoprefixerを使う方法（エラーの対応方法）](https://devsakaso.com/gulp-autoprefixer/)
[初心者向けのgulpの導入②ベンダープレフィックスを付ける](https://newsite-make.com/gulp-autoprefixer/)
[.browserslistrcで対象ブラウザを指定する](https://qiita.com/takeshisakuma/items/0bc1c39ee976bd1f52d7)