2017年12月28日に The Problem with gulp-util という記事が公開された。
gulp をウォッチしていたわけではないのだが、たまたま残された gulp 資産を触っている時に deprecation warning がコンソールに出力され、そのメッセージ中にこの記事へのリンクがあった。
warning gulp > gulp-util@3.0.8: gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5
記事の内容を要約すると以下のようになる。
TL;DR
- gulp v4 リリースにあたり gulp-util はもう deprecation です
- gulp-util はただの便利関数群なので使用している機能に応じて個別のライブラリに置き換えてください
- 6752個ものライブラリが依存している… migration を手伝いましょう
同記事を抄訳したり加筆したりしつつ、もう少し詳細を見ていく。
A little postmortem
先週 GitHub で公開した gulp v4.0.0-alpha.3、これが破壊的変更を含むとは知っていたがどれほど広範囲に影響が及ぶかは想像していなかった。これは gulp-util に依存する6,752個のモジュールのためだ。だいたいは古くなった Vinyl を使用している*1。
Why deprecation now?
gulp-util はただのモジュールの集まりなので2014年以来ずっと廃止するつもりでいた。ロギングのためだけになぜその他の無駄なモジュール、たとえば beeper もダウンロードしなければいけないのだろうか?プラグインのダウンロードサイズを大幅に増やすだけだ。皆がそれぞれ必要とする個々のモジュールを使うよう期待していたが、みな現状維持を選んでしまったらしい。
移行パスはそう複雑でないと踏んでいたが、先週の変更でこれは予想以上の大きな問題だとわかった。 古い Vinyl には互換性がないにも関わらずいまだ多くのプラグインで使用されている。 しかし Vinyl v2 は glup-util 付きではリリースされない。これは、我々がプラグインの作者たちに個々のモジュールへ移行してもらいたいからだ。
結果、gulp-util で警告を出すことにした。これは私たちが望んでいたエレガントな移行ではないのだが…。もしあなたが使用するプラグインが gulp-util に依存している場合、インストール時に deprecation 予定が通知される。修正を行うまではどのプラグインが警告を引き起こしているのかは分からない。
もし gulp-util に依存したプラグインが gutil.File API を使用していないのなら、そのプラグインは壊れていないかもしれない。 その場合は緊急ではないが、それでも gulp-util から離れるべきだ。
Help us fix the ecosystem
これらの手順でプラグイン作成者の gulp-util からの移行を助けよう。
npm ls gulp-util
を実行して、依存するプラグインのリストを取得する- それぞれのプラグインに対して npm issue {PLUGIN NAME} を実行し、issue tracker をブラウザで開く
- issue をオープンするか、以下の API を置き換えて gulp-util を削除するようにした pull request を作る
※ コードの例は自分が実際に置換するときに使った方法(随時追記する、かも)
gutil.File
=> https://www.npmjs.com/package/vinyl
const gutil = require('gulp-util') new gutil.File() # should be const Vinyl = require('vinyl') new Vinyl()
gutil.replaceExtension
=> The.extname
property on vinyl objects or https://www.npmjs.com/package/replace-ext
const gutil = require('gulp-util') gutil.replaceExtension(path, newExtention) # should be const replaceExt = require('replace-ext') replaceExt(path, newExtention)
gutil.colors
=> https://www.npmjs.com/package/ansi-colors
const gutil = require('gulp-util') gutil.colors.red(message) # should be # Node 4 以降 const fancyLog = require('chalk') chalk.red(message) # Node 0.10 のような古いバージョンをサポートする場合 const colors = require('ansi-colors') colors.red(message)
gutil.date
=> https://www.npmjs.com/package/date-formatgutil.log
=> https://www.npmjs.com/package/fancy-log
const gutil = require('gulp-util') gutil.log(message) # should be const fancyLog = require('fancy-log') fancyLog(message)
gutil.template
=> https://www.npmjs.com/package/lodash.template
const gutil = require('gulp-util') gutil.template(tmpl, data) # should be const template = require('lodash.template') template(tmpl)(data)
gutil.env
=> https://www.npmjs.com/package/minimist
const gutil = require('gulp-util') gutil.env.production # should be const parseArgs = require('minimist') const env = parseArgs(process.argv.slice(2)) env.production
gutil.beep
=> https://www.npmjs.com/package/beepergutil.noop
=> https://www.npmjs.com/package/through2
const gutil = require('gulp-util') gutil.noop() # should be const through = require('through2') through.obj()
gutil.isStream
=> Use the.isStream()
method on vinyl objectsgutil.isBuffer
=> Use the.isBuffer()
method on vinyl objectsgutil.isNull
=> Use the.isNull()
method on vinyl objectsgutil.linefeed
=> Use the string'\n'
in your codegutil.combine
=> https://www.npmjs.com/package/multipipegutil.buffer
=> https://www.npmjs.com/package/list-streamgutil.PluginError
=> https://www.npmjs.com/package/plugin-error
const gutil = require('gulp-util') new gutil.PluginError() # should be const PluginError = require('plugin-error') new PluginError()
(抄訳終わり)
現状
gulp-util, gulp のメンテナを中心に以下の issue でエコシステム全体のマイグレーションを進めている。
6,000個以上もあるので全てをまかなうのは無理そうだが、多く利用されているものから順次対応していくそうだ。
言い換えればコントリビューションチャンスなので自分も幾つか Pull Request を出してみた。メンテナがかなり精力的に色んなライブラリを直しているようなので、作業がバッティングしないよう issue や PR をちゃんとチェックするか、マイナーなライブラリから始めるとよさそう。まぁ、gulp 周りは死んでいるライブラリも多いのでマイナーなものだと永遠にマージされない可能性もあるが…。
*1:Vinyl は仮想ファイルオブジェクトを扱うライブラリ。ビニールと書くと聞き馴染みがある