gulp-cssnextにPostCSSプラグインを追加する方法


cssnextをgulpで使ってみたかったので、gulp-cssnextを導入してみたのですが、プラグインの追加方法でちょっとつまづいたので、経緯と解決法をまとめてみました。

基礎知識

cssnextは、CSSの先行実装を、現状のブラウザが解釈できるCSSに変換してくれるポストプロセッサーです。
cssnextは、PostCSSのラッパーに当たるツールなので、その機能を内包しています。

前提

CSSのコンパイルはPostCSSの機能をラップしているgulp-cssnextにて行う。
gulp-postcss側から、cssnextを用いてコンパイルするのではないやり方)

gulp-cssnextのインストール

プロジェクトのルートディレクトリで以下のコマンドを実行。

$ npm i gulp-cssnext --save-dev

CSSのコンパイル

gulpfile.jsのタスクは以下のような形で記述すれば、CSSのコンパイルは可能。

gulpfile.js
var gulp = require('gulp');
var cssnext = require('gulp-cssnext');

var paths = {
  'src': 'src/',
  'dist': 'dist/'
}

gulp.task("css", function() {
  return gulp.src(paths.src + 'css/*.css')
    .pipe(cssnext({
        compress: false,
        import: true
    }))
    .pipe(gulp.dest(paths.dist + 'css/'))
});

ただし、gulp-cssnextには、importなどの機能はデフォルトで実装されているが、
Sassのようなネストやミックスインといった機能を使用するためには、プラグインを追加する必要がある模様。

プラグインのオプションを追加

公式サイトによれば、PostCSSのプラグインを追加するには、このようにプラグイン名を指定して読みこめば良い、とあるので、gulpのタスクにオプションを追記してみる。

※ここでは、Sassのようなシンプルな変数表記を実現するpostcss-simple-varsプラグインを追記した。

gulpfile.js

gulp.task("css", function() {
  return gulp.src(paths.src + 'css/*.css')
    .pipe(cssnext({
        compress: false,
        import: true,
        plugins: [
          require("postcss-simple-vars")
        ]
    }))
    .pipe(gulp.dest(paths.dist + 'css/'))
});

その上で、ソース側のCSS内でネストを使ってコンパイルしてみると、以下のようなエラーが出てしまい、実行できなかった。

Error: Cannot find module 'postcss-simple-vars'

プラグインのインストール

これは、プラグイン自体がインストールされていないので当然かと思い、プロジェクトのルートディレクトリで下記のコマンドを実行してみた。

$ npm i postcss-simple-vars --save-dev

すると、今度はCSSのコンパイルに成功。

試しに、Sassライクな変数を使ってみると、思い通りに変換できていることも確認できた。

src/style.css
$textcolor: #000;

body {
  color: $textcolor;
}
dist/style.css
body {
  color: #000;
}

まとめ&分かったこと

  • cssnextはPostCSSの機能をラップしている
  • gulp-cssnextも、それ単体としてPostCSSをラップしている
  • gulp-cssnextが現時点で内蔵している機能やプラグインはデフォルトで使用できる
  • gulp-cssnextに実装されていないPostCSSプラグインを使いたい場合は、requireするだけではなく、自分で個別にインストールする必要がある
  • プラグインをインストールする場所は、プロジェクトのルートディレクトリでnpm installすればOK

注意点

基本的には上記のやり方で問題なさそうだが、プラグインによっては読み込み順や、相互に依存しているものもあるようなので、注意が必要。

例えば、Sassのようなミックスインを可能にするpostcss-mixinsは、 postcss-simple-varsとpostcss-nestedの前にセットする必要があると書かれているので、下記のようにプラグインを指定する。

gulpfile.js

gulp.task("css", function() {
  return gulp.src(paths.src + 'css/*.css')
    .pipe(cssnext({
        compress: false,
        import: true,
        plugins: [
          require("postcss-mixins"),
          require("postcss-simple-vars"),
          require("postcss-nested")
        ]
    }))
    .pipe(gulp.dest(paths.dist + 'css/'))
});