JavaScriptやCSSには人間が読みやすいよう、改行やスペースを設けたり、パット見て何に利用するかわかりやすい変数名をつけるわけですが、これは対人間用であってそれを実行する機械にとっては邪魔でしかありません。変数は1文字あれば十分ですし、改行やスペースなどのいわゆる「ホワイトキャラクター」はそもそも不要です。
そんなときに利用するのがminify。 webpackなどを利用していれば、最終的な出力時に自動的にやってくれますが、手元で個別のファイルに対して実行したいときがありますよね。今回はwebpackも内部で採用しているUglifyJSと、CleanCSSのCLIツールを利用して、JavaScript/CSSのminifyを行ってみます。
JavaScriptをminifyする
インストール
npmで一発で入ります。-g
オプションを忘れずに。
$ npm install -g uglify-js
今回は3.6.0が入りました。
$ uglifyjs --version uglify-js 3.6.0
利用方法
大抵の場合は以下のオプションをつけて実行すれば適切に変換してくれます。
$ uglifyjs --compress --mangle -- foo.js
試しに簡単なJavaScriptをminifyしてみます。
function echo(str){ // コンソールに出力する console.log(str); } echo("Hello");
以下のように改行や不要なスペース、セミコロン(;)、コメント分などが削除され、変更可能な変数が必要最小限の文字数に縮められているのがわかります。
$ uglifyjs --compress --mangle -- foo.js function echo(o){console.log(o)}echo("Hello");
私の場合、毎回オプションを指定するのが面倒なのでalias
の設定をしています。
$ vi ~/.zshrc alias minifyjs='uglifyjs --compress --mangle --' $ minifyjs foo.js function echo(o){console.log(o)}echo("Hello");
注意点
なお、uglifyjsはES2015(ES6)以降のナウい構文には対応していません。以下のようなコードを投げるとエラーになります。
const sum = (a, b)=>{ return(a + b); }; console.log( sum(1, 2) );
ご覧の通り、冒頭のconst
で早速コケてますねw
$ minifyjs foo.es6 Parse error at foo.es6:1,0 const sum = (a, b)=>{ ^ ERROR: Unexpected token: keyword «const»
もしES2015をminifyする場合には、一度Babelなどのトランスパイラを通すか、uglify-esを利用する必要があります。
CSSをminifyする
インストール
こちらもnpmで一発で入ります。
$ npm install -g clean-css-cli
今回は4.3.0が入りました。
$ cleancss --version 4.3.0
利用方法
通常、ファイル名を指定するだけです。
$ cleancss foo.css
以下のような簡単なCSSをかけてみます。
@charset "UTF-8"; /* リンク上にマウスが乗ったとき */ a:hover{ color: lightgoldenrodyellow; } .foo{ margin-bottom: 10px; margin-top: 20px; } .bar{ }
以下のように余計な改行、スペース、不要なセミコロン(;)、コメント文、内部にプロパティが一切ない物(.bar
)が消えてなくなりました。また長い色名がRGB値に変換されています。
$ cleancss bar.css @charset "UTF-8";a:hover{color:#fafad2}.foo{margin-bottom:10px;margin-top:20px}
この他にも様々な最適化が行わていますが、詳しくは公式ドキュメントのOptimization levels
の項目をご覧ください。
またJSと合わせる目的でalias
の設定をしていますが、これはお好みでどうぞ。
$ vi ~/.zshrc alias minifycss='cleancss' $ minifycss bar.css @charset "UTF-8";a:hover{color:#fafad2}.foo{margin-bottom:10px;margin-top:20px}