gulp-cssnextにpostcss-nestedプラグインを追加したらエラーが発生したので対処してみた


gulp-cssnextにPostCSSを追加する方法については、以下のエントリーにて紹介しました。

ところが、Sassのようなセレクターのネストを実現するpostcss-nestedプラグインを導入しようとしたところ、エラーが起きてしまい、うまくいかなかったので、経緯と解決策をまとめてみました。

前提

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-nestedなどのプラグインは、現状で内蔵されていない模様。

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

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

gulpfile.js

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

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

Error: Cannot find module 'postcss-nested'

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

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

$ npm i postcss-nested --save-dev

すると、今度はコンパイル時に以下のエラーメッセージが表示され、処理が中断。

Your current PostCSS version is 4.1.16, but postcss-nested uses 5.0.4. Perhaps this is the source of the error below.

PostCSSのアップデート

エラーメッセージ通りに、これはPostCSSのバージョンが一致してないため、との解釈でPostCSSをアップデートしてみることに・・。

ここで疑問なのが、「PostCSS」はどこにインストールされているのか?というところ。

cssnextがPostCSSをラップしているのだから、当然その中にあるはず、ということで/node_modules/の中を見てみると、下記ディレクトリ以下にPostCSS本体やPostCSSのプラグインらしきファイルが入っていることが分かった。

./node_modules/gulp-cssnext/node_modules/cssnext 

そこで、このディレクトリ上でターミナルを開いて、以下のコマンドを実行してみた。

npm i [email protected] --save

すると、PostCSSのバージョンが5.0.4にアップデートされたので、先ほどのエラーが解消。

これで、postcss-nestedを用いたCSSのネスト機能が利用できるようになった。

まとめ&分かったこと

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

懸念点

応急処置として、ひとまず上記の運用で問題なさそうだが、gulp-cssnext自体をアップデートした際に、PostCSSのバージョンが戻ってしまうのではないか?という点が心配。

いずれにしても、そのうちgulp-cssnext自体がアップグレードされれば、上記エラーは解消されるような気もするのですが・・。