bower
webpack

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

More than 3 years have passed since last update.


やりたいこと

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通さずに評価したいんだが、やり方がわからんので、今は別途読み込んでる。誰かやり方わかったら教えてほしい…