Minify Rubyをリリースした

大阪Ruby会議04向けにリリースした Minify Ruby についてとりあげます。

ざっくりいうと JavaScript の UgilifyJS や Terser のような位置付けで、Ruby のソースコードを Minify する Gem です。

github.com

使い方

使い方は README.md に記しているとおりですが、コマンドラインからであれば、minifyrb コマンドを叩くのがシンプルです。

$ gem i minifyrb
$ minifyrb path/to/file.rb

これで minify されたコードが標準出力に出力されます。echo 'puts :hello' | minifyrb といったパイプでの標準入力からの使い方や、-o オプションを使ったファイル出力が可能です。

もう少し実用的 (とは?) な使い方としては、まず Gemfile に minifyrb を追加します。

# Gemfile
gem 'minifyrb'

続いていつもの流れで bundle install を実行。

$ bundle install

次に Rakefile へのタスク追加をします。

# Rakefile
require 'minifyrb/rake_task'

Minifyrb::RakeTask.new

これによって bundle exec rake minifyrb で実行できるようになります。この bundle exec rake minifyrb はディレクトリ配下の *.rb ファイルに対して直接 minify をしますので、git リポジトリで管理されていることを推奨します。

$ bundle exec rake minifyrb

少し大きなもので使いたい場合はこれがおすすめです。余談ですが、私が大阪Ruby会議04の発表デモで使っていたコマンドはこちらになります。

対象の処理系

現状では Ruby 3.3 以上のパースを行う Prism を構文解析のエンジンにしている関係で、Ruby 3.3 以上が minifyrb の処理対象です。もし古い Ruby で使いたいようなユースケースがあれば、ユースケース次第でサポートを考えてみますのでお声掛けください (もちろん必ずしもお応えできるかはわかりません) 。

既知の課題

まだバグがあります。

簡単なプログラムであれば minify によって壊れることはあまりないかもしれませんが、弱点のひとつにヒアドキュメントがあります (そうヒアドキュメントです) 。 また、登壇後にぺんさんに教えてもらったp +a; p (1;2) が p+a;p(1;2) のシンタックスエラーになる問題は 0.1.0 時点で未解決です (それはそう) 。

マジックコメントについても minifyrb によって削除しますが、frozen string literal マジコメは frozen を解くだけなので大きな問題はなさそうですが、String#frozen? のようなメソッドを使った処理分岐があると問題が出ます。またエンコーディングに対するマジックコメントが UTF-8 以外の場合は、スクリプトエンコーディングの関係で問題が出る可能性があります。このあたりはマジックコメントを消すか残すかする互換オプションを設けるか、それともどちらかに割り切るかはまだ決めていない段階です。

開発者ノート

2019年の平成Ruby会議01向けに実装した RuboCop Faker 以来、4年半ぶりくらいの新作 Gem です。その RuboCop Faker はいまはまさかの 10,000,000 ダウンロード超えしていて、マジかという気持ち。

rubygems.org

RuboCop Faker は現世の益を目的に明確な課題を解くために実装したものでしたが、今回の Minify Ruby は現世の益を目的にしていないもので、RuboCop オートコレクトのマッチポンプ以外で、どんな現実世界の問題を解くユースケースが誕生するか楽しみです。

誕生した背景や設計的な部分は以下のスライドをご参照ください。

また関連する記事として、大阪Ruby会議04での話は以下をご参照ください。

koic.hatenablog.com