webpackでbower使って外部ライブラリの依存解決する

  • 81
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

やりたいこと

npmよりbowerのほうがクライアントパッケージは多いので、そっちから引っ張りたい。有名な奴はあるけどjqueryプラグインとかは全然足りない。

具体的には、

bower install jquery-textcomplete --save

とかして

require('text-complete')

したい

解決方法

bower_components以下のディレクトリもrequire pathにいれて、resolverプラグインで解決するようにする。

というかこの記事でやってることは、基本的には usage with bowerのまんまなんだけど…

実例

var webpack = require('webpack');
var path = require('path');

module.exports = {
  output: {
    filename: 'app.js'
  },
  resolve: {
    root: [path.join(__dirname, "bower_components")],
    extensions: ["", ".js"]
  },
  plugins: [
    new webpack.ResolverPlugin(
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
    )
  ]
}

これで bower install jquery したやつが

var $ = require('jquery')

できる

問題

bowerパッケージ、基本的にはbower.jsonのmain属性で指定されたファイルをrequireしようとするんだけど、bower.jsonの定義上、必須要素ではないので、結構な数のライブラリがそのままrequireできない問題がある。

そういうときはrequire時に無理やりファイルパスをたどったりする。
具体的にはこんな感じになる。

require('foo/dist/foo');
Foo.bar()

この問題を解決するために、browserifyやmain-bower-filesといったライブラリでは、overridesという属性を使ってユーザー側で定義を上書きする仕様を導入して対応してきたんだけど、webpackのこの方法ではoverridesを見てくれないのでファイル名を解決できない。

Overrides · Issue #585 · bower/bower

overridesはこんな風に書く。

  "overrides": {
    "backbone": {
      "dependencies": {
        "lodash": "*"
      },
      "main": "backbone.js"
    }
  }

とりあえずwebpackにIssue立てておいた。
Support 'overrides' option for bower.json · Issue #552 · webpack/webpack

とはいえ、webpackはrequire先のファイルを自由に掘れるので、あんまり関係ない気がする。

あと中途半端にrequire.js用コードや、window変数やglobal変数みてるやつがcommon.js環境下で動かないことが多々あった。具体的に言うとraphael.jsとraven.jsが動かなかった。ワークアラウンドとして無理やりcommonjs通さずに評価したいんだが、やり方がわからんので、今は別途読み込んでる。誰かやり方わかったら教えてほしい…