背景
jQuery UIを使っているJavaScriptアプリケーションをbrowserifyをつかってバンドルにしたいことがあります。今どきありえないとは思うかもしれませんが、まれにあります。
jQuery UIはnpmパッケージをAMDモジュール形式で配布しています。
注意:jQuery UIの最新バージョンは2016年9月にリリースされました。新規の開発に使うのはオススメしません。
問題
browserifyはAMDモジュールそのものをバンドルすることはできますが、モジュールが依存するモジュールを解決できません。つまり次のように書くだけではjQuery UIのダイアログは使えません。
require('jquery-ui/ui/widgets/dialog')
次のように依存するすべてのモジュールを列挙する必要があります。
require('jquery-ui/ui/version')
require('jquery-ui/ui/data')
require('jquery-ui/ui/plugin')
require('jquery-ui/ui/unique-id')
require('jquery-ui/ui/tabbable')
require('jquery-ui/ui/focusable')
require('jquery-ui/ui/safe-blur')
require('jquery-ui/ui/keycode')
require('jquery-ui/ui/safe-active-element')
require('jquery-ui/ui/widget')
require('jquery-ui/ui/widgets/mouse')
require('jquery-ui/ui/widgets/button')
require('jquery-ui/ui/widgets/resizable')
require('jquery-ui/ui/widgets/draggable')
require('jquery-ui/ui/widgets/dialog')
実はこれで全部ではありません。しかも不足しているモジュールは実行するまでわかりません。
解法
deamdifyというトランスフォームモジュールをつかいます。
deamdifyはその名の通り(?)AMDモジュールをNodeモジュールに変換します。
Nodeモジュールになってしまえばbrowserifyが依存関係を解決してくれます。
たとえば次のようにdeamdify
をglobal-transform
として指定します。
browserify -g deamdify index.js -o bundle.js
deamdify
のREADMEでは
browserify -t deamdify main.js -o bundle.js
と書かれていますが、-t
ではうまくいきませんでした。トランスフォームモジュールを指定しないときと同じように実行時にモジュールの不足が判明します。
代わりに-g
を指定すると、期待通りに依存モジュールの取り込みに成功します。
-g
の謎
-t
の代わりに-g
を指定する必要があるのが、jQuery UI
との組み合わせ問題か、deamdify
のREADMEの問題かははわかりませんでした。
私は次のサンプルコードから、-g
オプションの指定方法を発見しました。
"prepublish": "browserify -g deamdify . > bundle.js"