React + BrowserifyプロジェクトでJS/CSS/HTMLを圧縮(Minify)する
ReactとMaterial UIを組み合わせると、それだけでBrowserifyで結合したJavaScriptファイルが1MB超えてしまうので、やっぱり圧縮とかした方が良いのかな―と思い、やり方を調べてみました。
※2015/08/03更新
Licensifyを開発された @t_wada さんから改良の連絡をいただいたので、Licensifyの最新版1.4.0をもとに内容を更新しました。
Licensify - Nodeモジュールのライセンスコメントを生成する
JSファイルを圧縮すると、ライセンスが記載されているコメントが消えてしまうという問題があるということで、本題の前に、Browserifyと組み合わせて、読み込んだNodeモジュールのライセンスコメントを生成してくれる Licensify を試しておくことにしました。
インストールはnpmから。
$ npm install licensify --save-dev
使い方は簡単で、Browserify実行時に -p licensify
を加えてあげるだけで、生成されたJSファイルの先頭に、モジュールとライセンスについてのコメントを付与してくれます。
$ $(npm bin)/browserify -t babelify src/app.jsx -p licensify -o build/app.js
生成されるコメントは、以下のようなものでした。
※2015/08/03更新
生成されたコメントをLicensify 1.4.0のものに差し替えました。
各モジュールのホームページURLが出力されるようになった他、最下部に This header is generated by licensify (https://github.com/twada/licensify)
というコメントが入るようになりました。この変更の効果については後述するUglifyJSの説明にて。
/** * Modules in this bundle * * my-react-boilerplate: * license: MIT * author: Umi Uyura * version: 0.0.1 * * process: * author: Roman Shtylman <shtylman@gmail.com> * maintainers: coolaj86 <coolaj86@gmail.com>, defunctzombie <shtylman@gmail.com> * homepage: https://github.com/shtylman/node-process#readme * version: 0.11.1 * * react: * license: BSD-3-Clause * maintainers: zpao <paul@oshannessy.com>, jeffmo <jeff@anafx.com>, sebmarkbage <sebastian@calyptus.eu>, spicyj <ben@benalpert.com> * homepage: https://github.com/facebook/react/tree/master/npm-react * version: 0.13.3 * * This header is generated by licensify (https://github.com/twada/licensify) */
UglifyJS/Clean-CSS/HTML Minifier - JS/CSS/HTMLを圧縮する
本題の方ですが、圧縮のためのツールは探すとゾクゾクと出てくるのですが、私は以下のものを使うことにしました。
対象 | ツール |
---|---|
JavaScript | UglifyJS 2 |
CSS | Clean-CSS |
HTML | HTML minifier |
理由としては、JSの圧縮ではUglifyJSが良く見かけたのと、HTML minifier内でHTMLに含まれるJSとCSSを圧縮するのにUglifyJSとClean-CSSを使っているようだったので、相性が良さそうかなと思ったという程度です。
あと、JSに関しては Uglifyify を使うことでBrowserifyと連携して圧縮することもできそうだったのですが、圧縮が必要なのは主に公開のタイミングだと考えて、CSSやHTML同様、単独のツールの方を入れることにしました。
これらも全てnpmでインストールできます。
$ npm install uglify-js --save-dev $ npm install clean-css --save-dev $ npm install html-minifier --save-dev
圧縮が必要になるのはページを公開するタイミングなので、プロジェクト内にそれ用の public
フォルダを用意して、そこに諸々出力する感じにしています。
UglifyJS
UglifyJSは、正確にはUglifyJS 2になっているようです。
JavaScriptを圧縮するにあたり1つ問題だったのが、先に生成したライセンスコメントの扱いです。
UglifyJSは、デフォルトではコメントを除去してしまうため、ライセンスコメントは残すようにしたいのです。
そのために --comments
というオプションがあるようですが、これは基本的にはJSDocスタイルの @license
もしくは @preserve
が含まれるコメントを残すという動きのようでした。
--comments all
というオプションもありますが、これは全てのコメントを残してしまうため、これはこれでやり過ぎです。
もう一つのオプションとして、 --comments
にJavaScriptの正規表現を渡すことで、それに該当するコメントを残すということができるようでした。
そこで、Licensifyが出力するコメントにある Modules in this bundle
を指定することで、それ以外のコメントだけ除去することができました。
$ uglifyjs build/app.js -o public/build/app.js --comments '/Modules in this bundle/'
※2015/08/03更新
@t_wada さんから連絡をいただき、私の当初の方法では今後動かなくなってしまう可能性があるということで、Licensifyの出力に手を加えてくださいました。
@umi_uyura licensify ご利用ありがとうございます。ヘッダ先頭部の文言は今後変わりうると考えたので、先ほどリリースした 1.4.0 からヘッダ最後尾にこのような印を入れてみました。ぜひ試して頂ければと思います。 https://t.co/eqzzDVuGyY
— Takuto Wada (@t_wada) August 3, 2015
先に示した出力例の通り、最後尾に generated by ...
というコメントが入るようになったので、UglifyJSへ以下のように指定することで、ライセンスヘッダのみを残して圧縮することができます。
$ uglifyjs build/app.js -o public/build/app.js --comments '/generated by licensify/'
@t_wada さん、ありがとうございました!
Clean-CSS
Clean-CSSに関しては、特に迷わず。
複数のファイルを結合したりいろいろできるようですが、現状はそこまでの規模でもないため、シンプルに済みました。
$ cleancss -o public/style/app.css style/app.css
HTML Minifier
初期状態では、あまり圧縮されないようだったので、いくつかオプションを設定することにしました。
オプションについてはコマンドの引数としても渡すことができますが、種類が豊富なので、別途設定ファイルを用意して、それを利用することもできるようです。
私は以下のオプションを変更しました。
オプション | 値 | 意味 |
---|---|---|
removeComments | false → true | コメントを除去する |
collapseWhitespace | false → true | 空白を除去する |
minifyJS | false → true | JavaScriptを圧縮する |
minifyCSS | false → true | CSSを圧縮する |
設定ファイルは以下のようになりました。
{ "removeComments": true, "removeCommentsFromCDATA": false, "removeCDATASectionsFromCDATA": false, "collapseWhitespace": true, "conservativeCollapse": false, "collapseBooleanAttributes": false, "removeAttributeQuotes": false, "removeRedundantAttributes": false, "useShortDoctype": false, "removeEmptyAttributes": false, "removeOptionalTags": false, "removeEmptyElements": false, "lint": false, "keepClosingSlash": false, "caseSensitive": true, "minifyJS": true, "minifyCSS": true, "ignoreCustomComments": [], "processScripts": [] }
設定ファイルは -c
で指定します。
$ html-minifier -c html-minifier.conf index.html -o public/index.html
設定ファイルのひな形は HTML minifierのGitHubリポジトリ に含まれています。
まとめ
このあたりをまとめて、 npm script
も設定したものをアップ。
umi-uyura/my-react-boilerplate
Reactを使ったちょっとしたツールなどの土台レベルなら、このくらいで良さそうですが、ファイル数が多くなってくると大変になので、そうなってきたらGulpなどのタスク管理系が必要になりそう。
参考
開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質
- 作者: Cody Lindley,和田祐一郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/06/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る