Upgrade to Pro — share decks privately, control downloads, hide ads and more …

browserifyことはじめ

Ryo Murayama
February 26, 2014

 browserifyことはじめ

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

Ryo Murayama

February 26, 2014
Tweet

More Decks by Ryo Murayama

Other Decks in Programming

Transcript

  1. browserify
    ことはじめ

    その仕組みと活用~
    東京Node
    学園 11
    時限目
    Ryo Murayama
    2014/2/26
    0

    View Slide

  2. About me
    Ryo Murayama ( )
    ユニバ株式会社
    JavaScript, Ruby, Java ...
    @hitsujiwool
    http://uniba.jp

    View Slide

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

    View Slide

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

    View Slide

  5. Usage

    View Slide

  6. browserify?
    CommonJS
    スタイルのコー
    ドをブラウザの実行コー
    ドに変換
    するツー

    初コミットは2010
    年9

    現在はバー
    ジョン3.30.2
    substack (James Halliday)

    View Slide

  7. Becoming a trend?
    GitHub
    Google Trend

    View Slide

  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
    '
    )
    )
    ;

    View Slide

  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
    '
    )
    ;
    }
    ;

    View Slide

  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
    ソー
    スコー

    View Slide

  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
    )
    ;
    }
    )
    ;

    View Slide

  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
    他にもたくさんあります

    View Slide

  13. With task runners
    grunt‑browserify
    gulp‑browserify

    View Slide

  14. browserify vs RequireJS
    CommonJS vs AMD
    preprocessing vs client driven (async)
    サー
    バサイドの資産を活用
    ひと言で表すと"Node.js Oriented"

    View Slide

  15. Architecture

    View Slide

  16. Overall process

    View Slide

  17. Overall process
    1. transform
    によるコー
    ドの変換処理 (transform)
    2.
    依存関係の探索 (detective)
    3.
    モジュー
    ルのパス解決 (browser‑resolve)
    4.
    ブラウザで実行可能なコー
    ドの生成 (browser‑pack)
    1~3
    を再帰的に実行して依存ツリー
    を探索した後、4
    で最終
    的なコー
    ドを生成

    View Slide

  18. module‑deps
    エントリポイントのファイルを受け取って、
    ReadableWritable Stream
    を返す関数
    ユー
    ザが指定したtransform
    を順々
    にpipe
    して実行
    detective (esprima)
    を使って生成したAST
    から依存モジュ

    ルを解析
    browser‑resolve
    でモジュー
    ルのパスを解決
    出力として流れるデー
    タは、
    依存関係を構造化したJSON

    View Slide

  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

    View Slide

  20. Plugins

    View Slide

  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
    から依存関係を解析する手前に通過する

    View Slide

  22. Why transforms imporant?
    多様なフロントエンドの生態系

    普通の」JavaScript
    AMD
    altJS (TypeScript, JSX, HaXe, CoffeeScript)
    テンプレー
    トエンジン (handlebars, mustache,
    underscore)
    パッケー
    ジマネー
    ジャ (bower, component)
    プリプロセッサとしてのtransform

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  29. And more ...
    ES6
    をES5
    にコンパイル
    fs.readFileSync()
    のインライン展開
    less
    のコンパイル
    es6ify
    brfs
    lessify
    などなど
    詳しくは を参照
    list of transforms

    View Slide

  30. Conclusion & Discussion

    View Slide

  31. Conclusion
    browserify

    Node
    ライクのモジュー
    ルシステム
    サー
    バサイドJS
    の資産を活用できる
    Stream
    との親和性が高い
    transform
    による柔軟な前処理

    View Slide

  32. Too much scope?
    なんでもかんでも任せすぎなのでは?
    browserify
    は「
    汎用的な」
    プリプロセッサ?
    Node
    で直接動くコー
    ドしかbrowserify
    しないのも手?
    タスクランナー
    との使い分け
    gulp‑coffee/coffeeify
    grunt‑contrib‑handlebars/hbsfy

    View Slide

  33. Further topics
    ビルドの速度計測、
    キャッシュや並列化
    ライブラリ配布の際のベストプラクティスとは?
    クライアント/
    サー
    バでコー
    ドの共有 (cf. )
    dnode

    View Slide

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

    View Slide