browserify-shimを使って、CDN経由で外部JSライブラリをrequireする

Browserifyをここ最近よく使うようになってきました。ReactのJSXやES2015のコンパイルもBrowserifyで行えるのでなかなか便利です。今回こちらのブログに自作のjQueryプラグインを導入したのですが、npm経由でインストールして、Browserifyを使ってrequireして読み込むようにしました。ただjQuery本体だけはCDN経由で読み込みたいと思い、browserify-shimを使ってみることにしました。その辺の話を書きたいと思います。

Browserifyとは

Browserifyはご存知の方も多いと思いますが、ブラウザで使用するJSファイルに対して、requireメソッドを使ったモジュールの読み込みを可能にしてくれるツールです。さらに依存関係を考慮し、複数のJSファイルを1つのファイルにまとめてくれる便利なツールです。

browserify
Browserify

インストールはnpmを使って行います。オプションに「-g」をつけるとシステムにインストールされて、コマンドラインからbrowserifyコマンドが使えるようになります。

$ npm install -g browserify

Browserifyの使い方など詳細は公式のサイトを見てください。

Browserifyの基本的な使い方

jQueryやAngularJSなどのJSライブラリに依存したWebアプリケーションを開発する際に、Browserifyを使用するとrequireメソッドでjQueryやAngularJSを読み込めるようになります。今回組み込んだjQueryプラグイン「jQuery.cb-slideheader.js」を例に、Browserifyの使用方法を軽く説明しておきます。

まずnpm経由でjQueryとjQueryプラグイン(cbslideheader)をインストールします。

$ npm install --save jquery cbslideheader

app.jsというjsファイルを作り、requireメソッドを使ってインストールしたjQueryとjQueryプラグインを読み込むために以下を記述します。

global.jQuery = require('jquery');
require('cbslideheader');

jQuery(function () {
  jQuery('.cb-header').cbSlideDownHeader();
});

browserifyを使って、ビルドします。

$ browserify app.js -o bundle.js

browserifyして作られたbundle.jsファイルをscriptタグで読み込めば、ブラウザで表示した時に機能するようになります。

<script src="bundle.js"></script>

browserify-shimを使う

上記のようにBrowserifyを使うとrequreでjQueryなどのJSライブラリを読み込むことができるようになります。ただし、外部のJSファイルを読み込んでビルドすると、ファイルサイズが大きくなり過ぎてしまう場合があります。読み込むファイルによっては、CDN経由で読み込んだ方が都合が良い場合もあります。そこで登場するのが「browserify-shim」です。

browserify-shimとは

browserify-shimは、CommonJSに対応していないモジュールをBrowserifyで使えるようにしてくれるツールです。browserify-shimには、以下のような特徴があります(READMEの特徴の部分を訳しました)。

  • エイリアス、ファイルへのパス、モジュールをグローバルwindowオブジェクトに結びつける識別子を指定することによってCommonJSに対応していないモジュールをBrowserifyで使えるようにする。
  • グローバルな名前空間の中にある他のライブラに依存しているshimmingライブラリにdependsを挿入する。
  • 自分のパッケージの依存関係内で設定されているshimsを適用する。

shimという言葉がよく出てきていますが、意味については以下を参照してください。

browserify-shimの使い方

browserify-shimをインストールするには、以下のコマンドを実行します。

$ npm i -D browserify-shim

Browserifyを実行する際に、browserify-shimの処理を行わせるために、package.jsonに以下を追加します。

{
  "browserify": {
    "transform": ["browserify-shim"]
  }
}
package.json

browserify-shimで行う処理を設定するために、package.jsonに以下を追加します。

{
  "browserify-shim": {
    "./js/vendor/jquery.js": "$",
    "three": "global:THREE"
  }
}
package.json

上記の設定の意味は以下の通りです。

  • ./js/vendor/jquery.jsをbundleの中に含めて、window.$をエクスポートします。
  • window.THREEthreeとして公開し、var three = require(‘three’)で使えるようにします。

その他、細かい依存関係の設定も行えるようになっています。詳細はbrowserify-shimのREADME.mdをご確認ください。

CDN経由でjQueryをrequireする

browserify-shimを使ってCDN経由でjQueryをrequireするには、browserify-shimの設定として、package.jsonに以下を記述します。これによりglobalに存在している$がjqueryのmodule.exportsとしてセットされvar jquery = require(‘jquery’)が使えるようになります。

{
  "browserify-shim": {
    "jquery": "global:$"
  }
}
package.json

上記で説明しましたが、Browserifyを実行する際に、browserify-shimの処理を行わせるために、package.jsonに以下を記述します。

{
  "browserify": {
    "transform": ["browserify-shim"]
  }
}
package.json

今回は、jQuery本体はインストールする必要はないので、jQueryプラグインのみインストールします。

$ npm i -D cb-slideheader

app.jsファイルを作成し、以下を記述します。jqueryとプラグインのcbslideheaderをrequireしています。

var jQuery = require("jquery");
require("cbslideheader");

$(document).ready(function () {
  $(".cb-header").cbSlideDownHeader();
});

ここでひとまずBrowserifyしてみます。

$ browserify app.js -o bundle.js

すると以下のように怒られました。「プラグイン側でjqueryが読み込めないよ」ということです。

$ browserify app.js -o bundle.js
Error: Cannot find module 'jquery' from '/Users/maechabin/Sites/Project/test/node_modules/jquery.cb-slideheader.js/dist'
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:46:17
    at process (/usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:173:43)
    at ondir (/usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:188:17)
    at load (/usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:69:43)
    at onex (/usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:92:31)
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:22:47

というのも、今回使用しているjQueryプラグインは、プラグイン内でjQueryをrequireするようになっているからです。コード内にrequire(‘jquery’)という記述があるにも関わらず、同じディレクトリ内にjqueryというモジュールがないよということです。これを解決するためにいろいろ試してみたんですが、不思議なことに以下でとりあえず無事ビルドすることができました。

{
  "browser": {
    "cbslideheader": "./node_modules/jquery.cb-slideheader.js/dist/jquery.cbslideheader.min.js"
  }
}
package.json

package.jsonにbrowserフィールドを追加し、そこに読み込みたいファイルのパスを記述しました。これによりBrowserifyによって、requre(‘cbslideheader’)した時に、./node_modules/jquery.cb-slideheader.js/dist/jquery.cbslideheader.min.jsが読み込まれるようになります。

理由はよくわかっていませんが、問題なくbrowserifyしてくれるようになりました。

$ browserify app.js -o bundle.js

実際のコードと手順

最後にコードと流れをまとめておきます。

npmでjQueryプラグインのインストール

$ npm install --save cbslideheader

package.json

{
  "name": "test",
  "version": "1.0.0",
  "browser": {
    "cbslideheader": "./node_modules/jquery.cb-slideheader.js/dist/jquery.cbslideheader.min.js"
  },
  "browserify-shim": {
    "jquery": "global:$"
  },
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  }
}
package.json

app.js

var jQuery = require("jquery");
require("cbslideheader");

$(document).ready(function () {
  $(".cb-header").cbSlideDownHeader();
});
app.js

browserifyの実行

$ browserify app.js -o bundle.js

HTMLファイルでbundle.jsを読み込む

<script src="bundle.js"></script>

まとめ

jQueryに限らず、CDN経由で使いたいライブライは他にもいろいろあると思います。そんな時はbrowserify-shimをどんどん使っていきたいですね。ドキュメントも英語ですが、それほど量はないので気合い入れれば全部読めると思います。最後にbrowserify-shimのドキュメント以外に参考にしたサイトを紹介しておきます。

コメント一覧

  • 必須

コメント