package.json の browser field 実践編
package.json の browser field 入門編 では、package.jsonのbrowser fieldの役割と機能について紹介しました。
本編では、この機能のbundlerごとの実装の違いと、それを回避する方法を説明します。
ここで取り上げる実装の違いとはずばりpathの解決方法です。
-
./から記述するかどうか -
.jsを記述するかどうか -
mainとの対応関係
この3つの要素が絡んできます。
なお、パス解決のresolverを指定できる系もあるようですが、ここでは各々のbundlerがデフォルトで用意しているresolverについて論じています。
(なぜなら、resolverを外部が指定しなければ意図通りbundleされないというのは、利用者にとってはbundleされないのとほぼ同義です)
調査したbundlerは以下です。
パス記述の組み合わせ
組み合わせ的には下記があります
-
./から記述するかどうか: 変換前と変換後のそれぞれに対して2通り = 4通り -
.jsを記述するかどうか: 変換前と変換後のそれぞれに対して2通り = 4通り -
mainの記述方法: 相対パス記述と.js記述のそれぞれで4通り、さらにbrowserフィールドに変換を指定しているか否かで2通り = 8通り
4 x 4 x 8 = 128通りものパターンがあります。
その全パターンについて、指定がうまくいくかどうかを表にしました。
表のよみかた
| main | from | to | browserify | webpack | rn-packager |
|---|---|---|---|---|---|
| file1 | file1 | file2 |
1行は、package.jsonと、bundlerごとの解釈結果を示しています。
この行は
{
"main": "file1",
"browser": {
"file1": "file2"
}
}
という意味です。
-
mainカラムはmainフィールドの値 -
fromカラムは、browserフィールドの最初のキー -
toカラムは、fromの値
この場合、webpack以外はうまくバンドルできたということを示しています。
全結果
| main | from | to | browserify | webpack | rn-packager |
|---|---|---|---|---|---|
| file1 | file1 | file2 | |||
| file1 | file1 | ./file2 | |||
| file1 | file1 | file2.js | |||
| file1 | file1 | ./file2.js | |||
| file1 | ./file1 | file2 | |||
| file1 | ./file1 | ./file2 | |||
| file1 | ./file1 | file2.js | |||
| file1 | ./file1 | ./file2.js | |||
| file1 | file1.js | file2 | |||
| file1 | file1.js | ./file2 | |||
| file1 | file1.js | file2.js | |||
| file1 | file1.js | ./file2.js | |||
| file1 | ./file1.js | file2 | |||
| file1 | ./file1.js | ./file2 | |||
| file1 | ./file1.js | file2.js | |||
| file1 | ./file1.js | ./file2.js | |||
| ./file1 | file1 | file2 | |||
| ./file1 | file1 | ./file2 | |||
| ./file1 | file1 | file2.js | |||
| ./file1 | file1 | ./file2.js | |||
| ./file1 | ./file1 | file2 | |||
| ./file1 | ./file1 | ./file2 | |||
| ./file1 | ./file1 | file2.js | |||
| ./file1 | ./file1 | ./file2.js | |||
| ./file1 | file1.js | file2 | |||
| ./file1 | file1.js | ./file2 | |||
| ./file1 | file1.js | file2.js | |||
| ./file1 | file1.js | ./file2.js | |||
| ./file1 | ./file1.js | file2 | |||
| ./file1 | ./file1.js | ./file2 | |||
| ./file1 | ./file1.js | file2.js | |||
| ./file1 | ./file1.js | ./file2.js | |||
| file1.js | file1 | file2 | |||
| file1.js | file1 | ./file2 | |||
| file1.js | file1 | file2.js | |||
| file1.js | file1 | ./file2.js | |||
| file1.js | ./file1 | file2 | |||
| file1.js | ./file1 | ./file2 | |||
| file1.js | ./file1 | file2.js | |||
| file1.js | ./file1 | ./file2.js | |||
| file1.js | file1.js | file2 | |||
| file1.js | file1.js | ./file2 | |||
| file1.js | file1.js | file2.js | |||
| file1.js | file1.js | ./file2.js | |||
| file1.js | ./file1.js | file2 | |||
| file1.js | ./file1.js | ./file2 | |||
| file1.js | ./file1.js | file2.js | |||
| file1.js | ./file1.js | ./file2.js | |||
| ./file1.js | file1 | file2 | |||
| ./file1.js | file1 | ./file2 | |||
| ./file1.js | file1 | file2.js | |||
| ./file1.js | file1 | ./file2.js | |||
| ./file1.js | ./file1 | file2 | |||
| ./file1.js | ./file1 | ./file2 | |||
| ./file1.js | ./file1 | file2.js | |||
| ./file1.js | ./file1 | ./file2.js | |||
| ./file1.js | file1.js | file2 | |||
| ./file1.js | file1.js | ./file2 | |||
| ./file1.js | file1.js | file2.js | |||
| ./file1.js | file1.js | ./file2.js | |||
| ./file1.js | ./file1.js | file2 | |||
| ./file1.js | ./file1.js | ./file2 | |||
| ./file1.js | ./file1.js | file2.js | |||
| ./file1.js | ./file1.js | ./file2.js | |||
| file3 | file1 | file2 | |||
| file3 | file1 | ./file2 | |||
| file3 | file1 | file2.js | |||
| file3 | file1 | ./file2.js | |||
| file3 | ./file1 | file2 | |||
| file3 | ./file1 | ./file2 | |||
| file3 | ./file1 | file2.js | |||
| file3 | ./file1 | ./file2.js | |||
| file3 | file1.js | file2 | |||
| file3 | file1.js | ./file2 | |||
| file3 | file1.js | file2.js | |||
| file3 | file1.js | ./file2.js | |||
| file3 | ./file1.js | file2 | |||
| file3 | ./file1.js | ./file2 | |||
| file3 | ./file1.js | file2.js | |||
| file3 | ./file1.js | ./file2.js | |||
| ./file3 | file1 | file2 | |||
| ./file3 | file1 | ./file2 | |||
| ./file3 | file1 | file2.js | |||
| ./file3 | file1 | ./file2.js | |||
| ./file3 | ./file1 | file2 | |||
| ./file3 | ./file1 | ./file2 | |||
| ./file3 | ./file1 | file2.js | |||
| ./file3 | ./file1 | ./file2.js | |||
| ./file3 | file1.js | file2 | |||
| ./file3 | file1.js | ./file2 | |||
| ./file3 | file1.js | file2.js | |||
| ./file3 | file1.js | ./file2.js | |||
| ./file3 | ./file1.js | file2 | |||
| ./file3 | ./file1.js | ./file2 | |||
| ./file3 | ./file1.js | file2.js | |||
| ./file3 | ./file1.js | ./file2.js | |||
| file3.js | file1 | file2 | |||
| file3.js | file1 | ./file2 | |||
| file3.js | file1 | file2.js | |||
| file3.js | file1 | ./file2.js | |||
| file3.js | ./file1 | file2 | |||
| file3.js | ./file1 | ./file2 | |||
| file3.js | ./file1 | file2.js | |||
| file3.js | ./file1 | ./file2.js | |||
| file3.js | file1.js | file2 | |||
| file3.js | file1.js | ./file2 | |||
| file3.js | file1.js | file2.js | |||
| file3.js | file1.js | ./file2.js | |||
| file3.js | ./file1.js | file2 | |||
| file3.js | ./file1.js | ./file2 | |||
| file3.js | ./file1.js | file2.js | |||
| file3.js | ./file1.js | ./file2.js | |||
| ./file3.js | file1 | file2 | |||
| ./file3.js | file1 | ./file2 | |||
| ./file3.js | file1 | file2.js | |||
| ./file3.js | file1 | ./file2.js | |||
| ./file3.js | ./file1 | file2 | |||
| ./file3.js | ./file1 | ./file2 | |||
| ./file3.js | ./file1 | file2.js | |||
| ./file3.js | ./file1 | ./file2.js | |||
| ./file3.js | file1.js | file2 | |||
| ./file3.js | file1.js | ./file2 | |||
| ./file3.js | file1.js | file2.js | |||
| ./file3.js | file1.js | ./file2.js | |||
| ./file3.js | ./file1.js | file2 | |||
| ./file3.js | ./file1.js | ./file2 | |||
| ./file3.js | ./file1.js | file2.js | |||
| ./file3.js | ./file1.js | ./file2.js |
3つとも成功したパターン
| main | from | to | browserify | webpack | rn-packager |
|---|---|---|---|---|---|
| file1.js | file1.js | ./file2 | |||
| file1.js | file1.js | ./file2.js | |||
| ./file1.js | ./file1.js | ./file2 | |||
| ./file1.js | ./file1.js | ./file2.js | |||
| file3 | ./file1.js | ./file2.js | |||
| ./file3 | ./file1.js | ./file2.js | |||
| file3.js | ./file1.js | ./file2.js | |||
| ./file3.js | ./file1.js | ./file2.js |
導き出された結論
-
toは./で始める必要がある -
fromは.jsで終わる必要がある -
fromは、それがmainを置き換えるものであるなら、mainと同じ値である必要がある -
fromは、それがmainを置き換えないものであるなら、どんなパターンでもよい -
fromは、mainと同じでない場合は./で始める必要がある
結論を覚えられなかった人へ
全部./と.jsをつけよう!mainもね!
mainにだけ付け忘れるとうまくいかないパターンがあるという罠があったわけです。
実験レポジトリ
これをcloneして、自身の手で確認してみてください (要 Node v6)。
Generatorを駆使して組み合わせのループをうまく実装している例にもなっています。
ご参考に。 昔書いたGeneratorの記事 も見てみてください。