browserifyことはじめ

06b57a84a9c0b0be14e53606fbec4a3c?s=47 Ryo Murayama
February 26, 2014

 browserifyことはじめ

東京Node学園 11時限目の発表資料

06b57a84a9c0b0be14e53606fbec4a3c?s=128

Ryo Murayama

February 26, 2014
Tweet

Transcript

  1. browserify ことはじめ ~ その仕組みと活用~ 東京Node 学園 11 時限目 Ryo Murayama

    2014/2/26 0
  2. About me Ryo Murayama ( ) ユニバ株式会社 JavaScript, Ruby, Java

    ... @hitsujiwool http://uniba.jp
  3. Outline browserify の概要と使い方 browserify の実装 さまざまなプラグイン (transform) まとめと展望

  4. See also browserify‑playground github.com/hitsujiwool/browserify‑playground

  5. Usage

  6. browserify? CommonJS スタイルのコー ドをブラウザの実行コー ドに変換 するツー ル 初コミットは2010 年9 月

    現在はバー ジョン3.30.2 substack (James Halliday) 作
  7. Becoming a trend? GitHub Google Trend

  8. Basic usage CLI b r o w s e r

    i f y s r c / m a i n . j s > p u b l i c / j a v a s c r i p t s / b u n d l e . j s programmable v a r b r o w s e r i f y = r e q u i r e ( ' b r o w s e r i f y ' ) ; v a r f s = r e q u i r e ( ' f s ' ) ; v a r b = b r o w s e r i f y ( ) ; b . a d d ( ' s r c / m a i n . j s ' ) . b u n d l e ( ) . p i p e ( f s . c r e a t e W r i t e S t r e a m ( ' p u b l i c / j a v a s c r i p t s / b u n d l e . j s ' ) ) ;
  9. With your own modules / / s r c /

    p e r s o n a l . j s v a r f o o = r e q u i r e ( ' . / f o o ' ) ; f o o ( ) ; / / s r c / f o o . j s v a r b a r = r e q u i r e ( ' . / b a r ' ) ; m o d u l e . e x p o r t s = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s f o o ' ) ; b a r ( ) ; } ; / / s r c / b a r . j s m o d u l e . e x p o r t s = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s b a r ' ) ; } ;
  10. With built‑in modules / / s r c / b

    u i l t _ i n . j s v a r E v e n t E m i t t e r = r e q u i r e ( ' e v e n t s ' ) . E v e n t E m i t t e r ; v a r e m i t t e r = n e w E v e n t E m i t t e r ( ) ; e m i t t e r . o n ( ' f o o ' , f u n c t i o n ( m e s s a g e ) { c o n s o l e . l o g ( m e s s a g e ) ; } ) ; e m i t t e r . e m i t ( ' f o o ' , ' s o m e m e s s a g e ' ) ; Node の組み込みモジュー ルも大半が使える 使えない場合はr e q u i r e ( ) が空のオブジェクトを返す 詳細は や を参照 Readme ソー スコー ド
  11. With npm modules / / s r c / n

    p m . j s v a r r e q u e s t = r e q u i r e ( ' s u p e r a g e n t ' ) ; r e q u e s t . g e t ( ' h t t p : / / l o c a l h o s t : 3 0 0 0 ' , f u n c t i o n ( r e s ) { c o n s o l e . l o g ( r e s . s t a t u s ) ; } ) ;
  12. Optional Parameters ‑r ‑‑require: 外部からのr e q u i r

    e ( ) を可能に b r o w s e r i f y - r . / s r c / e x p o r t e d . j s : e x p o r t e d ‑‑noparse: 依存関係の探索を省略 b r o w s e r i f y s r c / m a i n . j s - - n o p a r s e s r c / s o m e _ i n d e p e n d e n t _ m o d u l e . j s ‑t ‑‑transform: 出力コー ドの変換( 重要!) b r o w s e r i f y s r c / m a i n . j s - t d e a m d i f y 他にもたくさんあります
  13. With task runners grunt‑browserify gulp‑browserify

  14. browserify vs RequireJS CommonJS vs AMD preprocessing vs client driven

    (async) サー バサイドの資産を活用 ひと言で表すと"Node.js Oriented"
  15. Architecture

  16. Overall process

  17. Overall process 1. transform によるコー ドの変換処理 (transform) 2. 依存関係の探索 (detective)

    3. モジュー ルのパス解決 (browser‑resolve) 4. ブラウザで実行可能なコー ドの生成 (browser‑pack) 1~3 を再帰的に実行して依存ツリー を探索した後、4 で最終 的なコー ドを生成
  18. module‑deps エントリポイントのファイルを受け取って、 ReadableWritable Stream を返す関数 ユー ザが指定したtransform を順々 にpipe して実行

    detective (esprima) を使って生成したAST から依存モジュ ー ルを解析 browser‑resolve でモジュー ルのパスを解決 出力として流れるデー タは、 依存関係を構造化したJSON
  19. browser‑pack [ { " i d " : " a

    1 b 5 a f 7 8 " , " s o u r c e " : " c o n s o l e . l o g ( r e q u i r e ( ' . / f o o ' ) ( 5 ) ) " , " d e p s " : { " . / f o o " : " b 8 f 6 9 f a 5 " } , " e n t r y " : t r u e } , { " i d " : " b 8 f 6 9 f a 5 " , " s o u r c e " : " m o d u l e . e x p o r t s = f u n c t i o n ( n ) { r e t u r n n * 1 1 1 } " , " d e p s " : { } } ] ReadableWritable Stream を返す関数 module‑deps の出力を受け取り、 実行コー ドを生成する qiita.com/hitsujiwool/items/b013577d361bfdef18a6
  20. Plugins

  21. transform module 実行コー ドの「 変換」 を司るモジュー ル m o d

    u l e . e x p o r t s = f u n c t i o n ( f i l e ) { r e t u r n t h r o u g h ( ) ; } b r o w s e r i f y s r c / m a i n . j s - t d e a m d i f y ファイルパスを受けとり、ReadableWritable Stream を返 す関数 ユー ザがbrowserify の実行時に指定する AST から依存関係を解析する手前に通過する
  22. Why transforms imporant? 多様なフロントエンドの生態系 「 普通の」JavaScript AMD altJS (TypeScript, JSX,

    HaXe, CoffeeScript) テンプレー トエンジン (handlebars, mustache, underscore) パッケー ジマネー ジャ (bower, component) プリプロセッサとしてのtransform
  23. With naive Style (deglobalify) / / p u b l

    i c / j a v a s c r i p t s / l e a k . j s w i n d o w . f o o = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s f o o ' ) ; } ; w i n d o w . b a z = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s b a r ' ) ; } ; ( f u n c t i o n ( e x p o r t s ) { e x p o r t s . b a r = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s b a z ' ) ; } ; } ) ( w i n d o w ) ; w i n d o w をe x p o r t に置きかえる( 結構強引) deglobalify
  24. With naive style (exposify) / / p u b l

    i c / j a v a s c r i p t s / l e a k . j s w i n d o w . f o o = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s f o o ' ) ; } ; w i n d o w . b a z = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s b a r ' ) ; } ; ( f u n c t i o n ( e x p o r t s ) { e x p o r t s . b a r = f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s b a z ' ) ; } ; } ) ( w i n d o w ) ; グロー バルリー クが解消されるわけではない exposify
  25. With AMD (deamdify) / / s r c / d

    e a m d i f y . j s v a r f o o = r e q u i r e ( ' . / a m d _ f o o ' ) ; f o o ( ) ; / / s r c / a m d _ f o o . j s d e f i n e ( f u n c t i o n ( ) { r e t u r n f u n c t i o n ( ) { c o n s o l e . l o g ( ' t h i s i s f o o ' ) ; } ; } ) ; AMD スタイルのモジュー ルを透過的にr e q u i r e ( ) deamdify
  26. With CoffeeScript (coffeeify) / / s r c / c

    o f f e e i f y . j s v a r f o o = r e q u i r e ( ' . / c o f f e e _ f o o . c o f f e e ' ) ; f o o ( ) ; / / s r c / c o f f e e _ f o o . c o f f e e m o d u l e . e x p o r t s = - > ( c o n s o l e . l o g ' t h i s i s f o o ' ) coffeeify
  27. With handlebars (hbsfy) / / s r c / h

    b s f y . j s v a r t e m p l a t e = r e q u i r e ( ' . / t e m p l a t e . h b s ' ) ; c o n s o l e . l o g ( t e m p l a t e ( { a n i m a l : ' s h e e p ' } ) ) ; / / s r c / t e m p l a t e . h b s I a m a { { a n i m a l } } テンプレー トをコンパイルして関数化 hbsfy
  28. With bower (debowerify) / / s r c / d

    e b o w e r i f y . j s v a r m o m e n t = r e q u i r e ( ' m o m e n t ' ) ; c o n s o l e . l o g ( m o m e n t ( ) . f o r m a t ( ) ) ; bower 由来のモジュー ルを透過的にrequire() できる debowerify
  29. And more ... ES6 をES5 にコンパイル fs.readFileSync() のインライン展開 less のコンパイル

    es6ify brfs lessify などなど 詳しくは を参照 list of transforms
  30. Conclusion & Discussion

  31. Conclusion browserify は Node ライクのモジュー ルシステム サー バサイドJS の資産を活用できる Stream

    との親和性が高い transform による柔軟な前処理
  32. Too much scope? なんでもかんでも任せすぎなのでは? browserify は「 汎用的な」 プリプロセッサ? Node で直接動くコー

    ドしかbrowserify しないのも手? タスクランナー との使い分け gulp‑coffee/coffeeify grunt‑contrib‑handlebars/hbsfy
  33. Further topics ビルドの速度計測、 キャッシュや並列化 ライブラリ配布の際のベストプラクティスとは? クライアント/ サー バでコー ドの共有 (cf.

    ) dnode
  34. ありがとうございました