gulpでSCSSコンパイル時にgulp-csscombを使っているとsourcemapが正しいファイル・行数を示さない


出る出るといいつつ全然出なくてすっかり忘れた頃にメジャーバージョンがリリースされ、v4になったgulpさんを今更ながら最新版で使おうとgulpfile.jsを再び書き直していた所、表題の件に気づきました。年末年始休暇の最終日を潰していろいろ調べてみたので、自分なりな解釈ではありますがその結果を共有しておきたいと思います。

症状

gulp-sourcemaps がどうにも正しく動作しておらず、全然関係ないファイルを指していたりしてました1。原因はなにかいろいろ調べては見たのですが、gulpfile.jsの指定方法はあってそうなので書き方の問題ではなさそうでした。

原因

gulp-csscombを使っていたからでした。

具体的には

gulp-sourcemapsgulp-csscombに対応していませんでした。整形された後のsourcemapが正常に出力されず、その結果デベロッパーツールで見てもおかしい行数やファイル名が示されていた、ということのようです。

https://github.com/gulp-sourcemaps/gulp-sourcemaps/wiki/Plugins-with-gulp-sourcemaps-support

gulp-sourcemaps側では今の所対応予定がなく、issueで同じような問い合わせがあったことに対して「その手の話は対応しないことにしている」とだけ返答してissueをcloseしています。

https://github.com/gulp-sourcemaps/gulp-sourcemaps/issues/359

一方でgulp-csscomb側は現在の所対応予定がないというか、そもそもメンテナンスされておらず、作者が後継の方を探しているといったような状態でした。

https://twitter.com/tonyganch/status/686992436871168000

対処方法

gulp-csscombgulp-sourcemapsを同時に使わない。

身も蓋もない感じですが、今の所これしかなさそうです。
例えばリリースビルドで圧縮せず綺麗な状態でcssを納品する必要があるのであれば、納品ビルドだけcsscombを適用し、sourcemapは使わないといった形であれば問題なく使えるかと思います2

ちなみにgulp 4.xでは

ビルトインでsourcemapsを出力出来るようになっています。ただ、これを使ってもcsscombと共存出来るというわけではありませんでした(結果はgulp-sourcemaps使用時と変わらなかった)。見た限りではそのように明言された箇所が見当たりませんでしたが、gulp-sourcemaps自体が内包された形になってるんでしょうか?

https://github.com/gulpjs/gulp

Built-in support for sourcemaps was added - the gulp-sourcemaps plugin is no longer necessary!

gulp 4.xでのビルトインsourcemapの使い方

src指定時と、dest指定時に引数として追記すればOKです(以下の書き方だとcss出力先と同じ箇所にmapファイルが生成される)。手元のgulpfile.jsからそのまま持ってきたので、適時お手元の環境に読み替えて見ていただければと思いますが、要はsrc(gulp.src())とdest(gulp.dest())に引数が増えているのですぐわかるかと思います。

gulpfile.js
// SASSコンパイル
task('sass', (done) => {
  return src(dir.src + 'scss/**/*.scss', {sourcemaps: true})
  // エラーの場合は停止せずに通知を出す
  .pipe($.plumber({
    errorHandler: $.notify.onError("Error: <%= error.message %>")
  }))
  // scssファイルをまとめて読み込む
  .pipe($.sassGlob())
  // コンパイル
  .pipe($.sass({outputStyle:'expanded'}))
  // cssプラグインの適用
  .pipe($.postcss(project.scss.plugins))
  // productionなら圧縮する
  .pipe($.if(isProduction, $.cleanCss()))
  // 出力先ディレクトリ
  .pipe(dest(dir.dist+dir.assets+'css', {sourcemaps: '.'}))
  // Sassを更新したらリロードせずに直接反映させる
  .pipe(browser.stream())
  // タスクの終了宣言
  done()
});

gulp-postcssgulp-clean-cssgulp-sourcemapsの頃から対応していたためか、併用しても大丈夫のようです。
https://github.com/gulp-sourcemaps/gulp-sourcemaps/wiki/Plugins-with-gulp-sourcemaps-support

終わりに。

我ながらよく今の今までsourcemapがおかしいことに気づかなかったなと思います…(browsersyncのlivereload絡みでおかしくなってるんだと勝手に思ってました)。

私なりにいろいろ調べた結果ではありますが、なんとか連休中には出したかったということもあり、調べが足りていない可能性もあります。
もし解決方法をご存知だったり、そもそもの原因や私の理解が間違っている事などありましたら、ぜひご指摘いただけると助かります。

それではまた。


  1. object/components/_sample.scss内に記述している内容が、sourcemapを通すとfoundation/mixins.scssになったりしてました。 

  2. よくよく考えると、私みたいに開発中のみsourcemaps+csscombを使っている方がおかしい気がしてきました。