31
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Browserifyの運用 〜 bundleを分ける

Last updated at Posted at 2015-02-07

Browserify使いはじめてしばらくたって、自分なりのコツがつかめてきた気がするのでまとめてみます。

まず今回のコンテキストとしては画面遷移をそれなりに含み、同じモジュールを各画面で使う前提。
SPAだとちょっと考え方が変わるかもしれません。

【対策以前】全部をbundleすると太る

Browserify覚えてしばらくは、ページ毎の実行部分も含めてbundle.jsにひとまとめしてたけど、各ページ共通部分があるにもかかわらず別ファイルになってしまい、ブラウザキャッシュも生かせず、ファイルサイズも肥大化して微妙だなぁと感じていました。ビルドも毎回でgulpタスクも重くなりがちでした。

  • 共通部分も別々のファイル
  • ブラウザキャッシュ活かせない
  • ファイルサイズ肥大化
  • ビルド重め

ファイル配置例

.
├── node_modules
│   ├── knockout
│   └── underscore
├── public
│   ├── index.html
│   └── static
│       └── js
│           ├── bundle1.js 
│           └── bundle2.js // bundle1と同じものが多く含まれている!
└── src
    ├── MyModule.js // 自作モジュール
    ├── page1.js // ページ固有のロジック
    └── page2.js // ページ固有のロジック

src/app.js

// src/page*.js
(function(){
var ko = require('knockout');
var _ = require('underscore');
var myModule = reqire('./src/MyModule.js');

// ページ固有の処理

})()

browserifyコマンド

// app.jsそのものをbundle
browserify src/page1.js > public/static/js/bundle1.js
// 別ページなら別bundle
browserify src/page2.js > public/static/js/bundle2.js

【対策】共有部分だけbundle

browserifyはbundleしたモジュール類を他のファイルからrequireで呼びだせるので、共通モジュールをbundleしたファイルと、各ページ固有ロジックを記述したファイルにわけることにしました。
そうすることで共有ファイルはブラウザキャッシュを活かせるし、各ページ固有のファイルサイズは小さくなります。requireするものが全部共有ファイルに入っているならば、ビルドも必要ありません。

  • 共通部分だけを一つのbundleファイルにする
  • 他のscriptからrequireで呼び出せる
  • ブラウザキャッシュ活かせる
  • ファイルサイズ縮小
  • ビルド頻度・重さ減少

ファイル配置例

.
├── node_modules
│   ├── knockout
│   └── underscore
├── public
│   ├── index.html
│   └── static
│       └── js
│           ├── bundle.js
│           ├── page1.js
│           └── page2.js
└── src
    └── MyModule.js

今回の例だとapp.jsでrequireするファイルはすべてbundle.jsに入っているので、app.jsをbrowserifyにかける必要はありません。そのままpublic/staic/jsに配置します。

browserifyコマンド

外部からrequireできるbundleを作る方法です。自作モジュール(src/MyModule.js)にモジュール名を割り当ててあげることで、モジュール名で呼び出せるようになるのがポイントです。

browserify -r knockout -r underscore -r ./src/MyModule.js:MyModule > public/static/js/bundle.js

同じことをgulpタスクで書くと以下。やはり{expose: 'MyModule'}で自作モジュールに名前をつけてあげるのがポイントです。

gulp taskバージョン

var browserify = require('browserify');
var source = require('vinyl-source-stream');

gulp.task('build', function() {
  return browserify()
    .require('underscore')
    .require('knockout')
    .require('./src/MyModule.js', {expose: 'MyModule'})
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./public/static/js/'));
});

public/static/js/page*.js

// src/app.js
(function(){
var ko = require('knockout'); // requireが使える
var _ = require('underscore');  // bundle.jsから読んでいる
var MyModule = reqire('MyModule'); //設定した名前で呼び出せる

// ページ固有の処理

})()

htmlで呼び出し

<script src="static/js/bundle.js"></script>
<script src="static/js/page*.js"></script>

別ファイルからrequireする方法はBrowserifyのDocumentの割と最初のほうに書いてあるので、最初からちゃんと読み込んで使っていればこうしてたかな、という感じもしますが最近やっと気がついたので。

もっといい運用あるよとか、ご意見ありましたらお願いします。

31
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?