Share
Embed
Transcript
34 slides
-
About me Ryo Murayama ( ) ユニバ株式会社 JavaScript, Ruby, Java
... @hitsujiwool http://uniba.jp -
browserify? CommonJS スタイルのコー ドをブラウザの実行コー ドに変換 するツー ル 初コミットは2010 年9 月
現在はバー ジョン3.30.2 substack (James Halliday) 作 -
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 ' ) ) ; -
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 ' ) ; } ; -
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 ソー スコー ド -
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 ) ; } ) ; -
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 他にもたくさんあります -
browserify vs RequireJS CommonJS vs AMD preprocessing vs client driven
(async) サー バサイドの資産を活用 ひと言で表すと"Node.js Oriented" -
Overall process 1. transform によるコー ドの変換処理 (transform) 2. 依存関係の探索 (detective)
3. モジュー ルのパス解決 (browser‑resolve) 4. ブラウザで実行可能なコー ドの生成 (browser‑pack) 1~3 を再帰的に実行して依存ツリー を探索した後、4 で最終 的なコー ドを生成 -
module‑deps エントリポイントのファイルを受け取って、 ReadableWritable Stream を返す関数 ユー ザが指定したtransform を順々 にpipe して実行
detective (esprima) を使って生成したAST から依存モジュ ー ルを解析 browser‑resolve でモジュー ルのパスを解決 出力として流れるデー タは、 依存関係を構造化したJSON -
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 -
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 から依存関係を解析する手前に通過する -
Why transforms imporant? 多様なフロントエンドの生態系 「 普通の」JavaScript AMD altJS (TypeScript, JSX,
HaXe, CoffeeScript) テンプレー トエンジン (handlebars, mustache, underscore) パッケー ジマネー ジャ (bower, component) プリプロセッサとしてのtransform -
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 -
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 -
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 -
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 -
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 -
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 -
And more ... ES6 をES5 にコンパイル fs.readFileSync() のインライン展開 less のコンパイル
es6ify brfs lessify などなど 詳しくは を参照 list of transforms -
Conclusion browserify は Node ライクのモジュー ルシステム サー バサイドJS の資産を活用できる Stream
との親和性が高い transform による柔軟な前処理 -
Too much scope? なんでもかんでも任せすぎなのでは? browserify は「 汎用的な」 プリプロセッサ? Node で直接動くコー
ドしかbrowserify しないのも手? タスクランナー との使い分け gulp‑coffee/coffeeify grunt‑contrib‑handlebars/hbsfy