Bowerとnpmの違いは何ですか?


1763

基本的な違いは何ですかbowerとはnpm?単純でシンプルなものが欲しいだけです。私は私の同僚の使用のいくつかを見てきましたbowerし、npm自分のプロジェクトでは交換可能にします。




7
この質問への答えは時代遅れのようです。フラットな依存関係をサポートするnpm 3を使用している場合、誰かが2016年に何をすべきか教えてもらえますか?wince npm3とbowerの違いは何ですか?現在のベストプラクティスは何ですか?
amdev 2016年

2
結論、@ amdev:bowerは非推奨になりました。npm(またはわずかな違いのみである糸)は、それがあるところです。私は実行可能な代替案を知りません。
XML

回答:


1914

すべてのパッケージマネージャーには多くの欠点があります。あなたはあなたが一緒に暮らすことができるものを選ぶ必要があります。

歴史

npmはnode.jsモジュールの管理を開始しました(そのため、パッケージはnode_modulesデフォルトで使用されます)が、Browserifyまたはwebpackと組み合わせると、フロントエンドでも機能します。

Bowerはフロントエンド専用に作成され、それを念頭に置いて最適化されています。

レポのサイズ

npmは、bowerよりもはるかに大きく、汎用のJavaScript(country-data国の情報やsorts、フロントエンドやバックエンドで使用できるソート関数など)を含みます。

Bowerのパッケージ数ははるかに少ないです。

スタイル等の取り扱い

Bowerにはスタイルなどが含まれています

npmはJavaScriptに焦点を当てています。スタイルは個別にダウンロードされるか、npm-sassまたはのようなものによって要求されますsass-npm

依存関係の処理

最大の違いは、npmはネストされた依存関係(デフォルトではフラット)を実行するのに対し、Bowerはフラットな依存関係ツリーを必要とする(ユーザーに依存関係の解決の負担をかける)ことです。

ネストされた依存関係ツリーは、依存関係が独自の依存関係を持つことができることを意味します。これにより、2つのモジュールが同じ依存関係の異なるバージョンを必要とする場合でも機能します。npm v3以降、依存関係ツリーはデフォルトでフラットになり(スペースを節約)、必要な場合にのみネストされます(たとえば、2つの依存関係に独自のバージョンのUnderscoreが必要な場合)。

一部のプロジェクトでは、フロントエンドパッケージにはBowerを使用し、Yeoman、Grunt、Gulp、JSHint、CoffeeScriptなどの開発者ツールにはnpmを使用しています。


資源


37
ネストされた依存関係ツリーがフロントエンドでうまく機能しないのはなぜですか?
LarsNyström2014年

24
フロントエンドのnpmパッケージもフラットな依存関係ツリーではないのでしょうか?「なぜ2つのパッケージマネージャーが必要なのか」に直面しています。ジレンマ。
Steven Vachon 2014年

38
「フラットな依存ツリー」とはどういう意味ですか?平らな木は何ですか-リスト?その時、それは木ではありません。
mvmn 2014年

14
実際には、パスもツリーです。それは単なる特別なケースです。WikiPediaから:「数学では、より具体的にはグラフ理論では、ツリーは2つの頂点が1つのパスで接続されている無向グラフです。」
ヨルゲンFogh

42
npm 3は、フラットな依存関係ツリーをサポートします。
vasa 2015年

361

この回答は、シンドレソルフスの回答への追加です。npmとBowerの主な違いは、再帰的な依存関係の扱い方です。これらは1つのプロジェクトで一緒に使用できることに注意してください。

オンNPMよくある質問(2015年9月6日からarchive.orgリンク)

依存関係をネストせずに依存関係の競合を回避することははるかに困難です。これはnpmが機能する方法の基本であり、非常に成功したアプローチであることが証明されています。

オンバウアーのホームページ:

Bowerはフロントエンド向けに最適化されています。Bowerは、パッケージごとに1つのバージョンのみを必要とするフラットな依存関係ツリーを使用して、ページの負荷を最小限に抑えます。

つまり、npmは安定性を目指しています。Bowerは最小限のリソース負荷を目指しています。依存構造を描くと、次のようになります。

npm:

project root
[node_modules] // default directory for dependencies
 -> dependency A
 -> dependency B
    [node_modules]
    -> dependency A

 -> dependency C
    [node_modules]
    -> dependency B
      [node_modules]
       -> dependency A 
    -> dependency D

ご覧のとおり、一部の依存関係が再帰的にインストールされます。依存関係Aには3つのインスタンスがインストールされています!

バウアー:

project root
[bower_components] // default directory for dependencies
 -> dependency A
 -> dependency B // needs A
 -> dependency C // needs B and D
 -> dependency D

ここでは、すべての固有の依存関係が同じレベルにあることがわかります。

では、なぜnpmを使用するのですか?

おそらく、依存関係Bには依存関係Cとは異なるバージョンの依存関係Aが必要です。npmはこの依存関係の両方のバージョンをインストールするため、どちらのバージョンでも機能しますが、Bowerは重複を好まないため競合を引き起こします(Webページに同じリソースをロードするため、非常に非効率的で費用がかかり、重大なエラーが発生する可能性もあります)。インストールするバージョンを手動で選択する必要があります。これにより、依存関係の1つが壊れる可能性がありますが、それはとにかく修正する必要があります。

したがって、一般的な使用方法は、Webページに公開するパッケージ(例:ランタイム、重複を回避する場所)のBowerであり、テスト、ビルド、最適化、チェックなど、他のもの(開発時間など)にnpmを使用します。、重複の心配が少ない場合)。

npm 3の更新:

npm 3は、Bowerとは異なる方法で動作します。依存関係をグローバルにインストールしますが、最初のバージョンでのみ発生します。他のバージョンはツリーにインストールされます(親モジュール、次にnode_modules)。

  • [node_modules]
    • dep A v1.0
    • dep B v1.0
      • dep A v1.0 (ルートバージョンを使用)
    • dep C v1.0
      • dep A v2.0(このバージョンはルートバージョンとは異なるため、ネストされたインストールになります)

詳細については、npm 3のドキュメントを読むことをお勧めします


4
「ソフトウェア開発はすべてトレードオフにかかっている」というのは、今ではほとんど決まり文句です。これは良い例です。を使用すると安定性を向上させるnpm 、リソースの負荷を最小限に抑える必要がありますbower
jfmercer 2015年

6
@シュレック私は暗黙的にあなたが実際に両方を使用できると述べています。最後の段落で述べるように、それらには異なる目的があります。それは私の目にはトレードオフではありません。
Justus Romijn 2015年

ああ、私はあなたを誤解しているようです。または、十分に注意深く読みませんでした。説明をありがとう。:-)どちらもトレードオフなしで使用できるのは良いことです。
jfmercer 2015年

4
@AlexAngas npm3の更新を追加しました。それはまだバウアーと比較していくつかの大きな違いがあります。nwerはおそらく常に複数のバージョンの依存関係をサポートしますが、Bowerはサポートしません。
Justus Romijn、2016年

npm 3が
亭に

269

TL; DR:日常の使用における最大の違いは、ネストされた依存関係ではありません...それは、モジュールとグローバルの違いです。

以前のポスターは基本的な違いのいくつかをうまくカバーしていたと思います。(npmのネストされた依存関係の使用は、大規模で複雑なアプリケーションの管理に非常に役立ちますが、それが最も重要な違いだとは思いません。)

ただし、Bowerとnpmの最も基本的な違いの1つを明確に説明した人がいないことに驚いています。上記の回答を読むと、npmのコンテキストでよく使用される「モジュール」という単語が表示されます。しかし、それは単なる構文の違いであるかのように、さりげなく言及されています。

しかし、モジュールとグローバル(またはモジュールと「スクリプト」)のこの区別は、おそらくBowerとnpmの最も重要な違いです。すべてをモジュールに配置するnpmアプローチでは、ブラウザーのJavascriptの記述方法を変更する必要があります。

バウアーアプローチ:<script>タグのようなグローバルリソース

ルートでは、Bowerは古いスクリプトファイルをロードします。これらのスクリプトファイルに何が含まれていても、Bowerはそれらをロードします。これは基本的に、Bowerがすべてのスクリプトをプレーン・オールド<script><head>HTMLに含めるのと同じことを意味します。

つまり、これまでと同じ基本的なアプローチですが、便利な自動化機能がいくつかあります。

  • 以前は、プロジェクトのリポジトリに(開発中に)JSの依存関係を含めるか、CDN経由で取得する必要がありました。これで、リポジトリで余分なダウンロードの重みをスキップでき、誰かがbower installローカルで必要なものをすばやく簡単に実行できます。
  • Bowerの依存関係がそので独自の依存関係を指定している場合bower.json、それらもダウンロードされます。

しかし、それを超えて、バウアーは私たちがjavascriptを書く方法を変えません。Bowerによってロードされたファイル内に含まれる内容については、何も変更する必要はありません。特に、これは、Bowerによってロードされたスクリプトで提供されるリソースが(通常、常にではないが)グローバル変数として定義され、ブラウザー実行コンテキストのどこからでも利用できることを意味します。

npmアプローチ:一般的なJSモジュール、明示的な依存関係注入

Nodeランドのすべてのコード(したがって、npmを介して読み込まれるすべてのコード)は、モジュールとして(具体的には、CommonJSモジュール形式の実装として、または現在はES6モジュールとして)構造化されています。したがって、NPMを使用してブラウザー側の依存関係を処理する場合(Browserifyまたは同じことを行う他の何かを介して)、Nodeと同じようにコードを構成します。

私が「なぜモジュールなのか」という問題に取り組んだよりも賢い人たちですが、ここにカプセルの要約があります:

  • モジュール内のすべてのものは事実上名前空間になっています。つまり、もはやグローバル変数ではなく、意図せずに誤って参照することはできません。
  • モジュール内の何かは、それを利用するために、特定のコンテキスト(通常は別のモジュール)に意図的に注入する必要があります
  • つまり、アプリケーションのさまざまな部分で同じ外部依存関係(たとえば、ロダッシュ)の複数のバージョンを使用でき、それらが衝突/競合することはありません。(これは驚くほど頻繁に発生します。独自のコードが1つのバージョンの依存関係を使用したいが、外部依存関係の1つが競合する別のバージョンを指定しているためです。または、それぞれ異なるバージョンを必要とする2つの外部依存関係があります。)
  • すべての依存関係は特定のモジュールに手動で挿入されるため、それらについて推論するのは非常に簡単です。あなたは事実を知っています:「これに取り組むときに考慮する必要がある唯一のコードは、私がここに注入するために意図的に選択したものです」
  • 注入されたモジュールのコンテンツでさえ、割り当てられた変数の背後にカプセル化され、すべてのコードが制限されたスコープ内で実行されるため、驚きと衝突はほとんど起こりません。依存関係の1つからの何かが、気付かないうちに誤ってグローバル変数を再定義する、またはそうする可能性ははるかに低くなります。(それはでき起こるができますが、通常はそれを行うためにあなたの方法のうちに行かなければならない、のようなものでwindow.variable。まだ発生しやすいという1件の事故が代入されthis.variable、それを実現していないことはthis、実際にありますwindow現在のコンテキストで。)
  • 個々のモジュールをテストしたいときは、非常に簡単に知ることができます。モジュール内で実行されるコードに影響を与えているもの(依存関係)は何か?そして、明示的にすべてを注入しているので、これらの依存関係を簡単に模倣できます。

私にとって、フロントエンドコードでのモジュールの使用は、結局のところ、推論とテストが容易な非常に狭いコンテキストで作業し、何が起こっているかについてより確実なものにすることです。


CommonJS / Nodeモジュールの構文の使用方法を習得するには、約30秒しかかかりません。モジュールとなる特定のJSファイル内で、まず、次のように、使用する外部依存関係を宣言します。

var React = require('react');

ファイル/モジュール内では、通常どおりに何でも行い、外部ユーザーに公開したいオブジェクトまたは関数を作成し、おそらくそれを呼び出します myModuleます。

ファイルの最後で、次のように、世界と共有したいものはすべてエクスポートします。

module.exports = myModule;

次に、ブラウザーでCommonJSベースのワークフローを使用するには、Browserifyなどのツールを使用して、これらの個々のモジュールファイルをすべて取得し、実行時にそれらのコンテンツをカプセル化し、必要に応じて相互に挿入します。

また、ES6モジュール(BabelなどでES5にトランスパイルする可能性が高い)は広く受け入れられており、ブラウザーとNode 4.0の両方で機能するため、それらの概要についても言及する必要があります。

このデッキでモジュールを操作するためのパターンの詳細。


編集(2017年2月):Facebookのは、最近のnpmの非常に重要な潜在的な置き換え/補足です。npmが提供するものに基づいて構築された高速で確定的なオフラインパッケージ管理。JSプロジェクトは一見の価値があります。特に、プロジェクトを簡単に入れ替えることができるためです。


編集(2019年5月)「Bowerがついに非推奨になりました。ストーリーの終わり。」(h / t:簡潔な要約については、以下の@DanDascalescu。)

また、Yarn はまだアクティブですが、Yarnの主要な機能の一部を採用すると、Yarnの勢いの多くはnpmに戻りました。


13
この回答がここにあったことをうれしく思います。他の人気のある回答はこの詳細に言及していません。npmを使用すると、モジュール式コードを作成する必要があります。
ファンメンデス

申し訳ありませんが、JavaScriptの土地のファジングをほとんど気にしない人からですが、小さなWebアプリケーションを使用するビジネスを運営しています。最近、npmを試すことを余儀なくされました。私たちが使っているツールキットでbowerを使用することから、darn webの開発に使用されています。最大の違いは待ち時間であり、npmには時間がかかります。剣の戦いをしている人たちが上司に「編集中」と叫んでxkcdの漫画を編集していることを思い出してください。それはnpmがバウアーに追加したものとほぼ同じです。
ペドロロドリゲス

129

2017-10月更新

バウアーはついに廃止れました。話の終わり。

古い答え

SpotifyのJavaScript開発者であるMattias Petter Johanssonから

ほとんどすべての場合、BowerよりもBrowserifyとnpmを使用する方が適切です。これは、Bowerよりもフロントエンドアプリのパッケージソリューションとして優れています。Spotifyでは、npmを使用してWebモジュール全体(html、css、js)をパッケージ化しており、非常にうまく機能します。

Bowerは、自身をWebのパッケージマネージャーとしてブランド化しています。これが本当なら素晴らしいだろう-フロントエンド開発者として私の人生をより良くしたパッケージマネージャーは素晴らしいだろう。問題は、Bowerがこの目的のための特別なツールを提供していないことです。これは、npmが提供していないことを知っているツールを提供していません。特に、フロントエンドの開発者に特に役立つツールは提供していません。フロントエンド開発者がnpmよりもBowerを使用するメリットはありません。

bowerの使用を中止し、npmあたりで統合する必要があります。ありがたいことに、それが起こっています。

モジュール数-bower対npm

browserifyまたはwebpackを使用すると、すべてのモジュールを大きな縮小ファイルに連結するのが非常に簡単になり、特にモバイルデバイスでのパフォーマンスに優れています。同じ効果を得るためにかなり多くの労力を必要とするBowerではそうではありません。

npmには、モジュールの複数のバージョンを同時に使用する機能もあります。アプリケーション開発をあまり行っていない場合、これは最初は悪いことと思われるかもしれませんが、Dependency hellを何度か試してみると、1つのモジュールの複数のバージョンを持つことができるのはかなり難しいことに気づくでしょう。素晴らしい機能。NPMは非常に便利含まれることに注意してください重複排除のツールを自動的にあなたが実際に場合にのみモジュールの2つのバージョンを使用することを確認することを持っている二つのモジュールの両方があれば-にすることができ、彼らは意志一つのモジュールの同じバージョンを使用しています。しかし、それができない場合は、非常に便利です。

(2016年8月現在、WebpackロールアップはBrowserifyよりも優れていると広く見なされています。)


7
<sarcasm> 'hello world' npmプロジェクトでさえ、実行するには300以上のモジュールが必要であることを覚えておいてください... </
sarcasm

1
「大きな縮小ファイル」が「パフォーマンス、特にモバイルデバイスにとって素晴らしい」とは思わない。まったく逆:帯域幅が制限されている場合、オンデマンドで読み込まれる小さなファイルが必要です。
Michael

あまり良いアドバイスではありません。ほとんどのnpmパッケージはnodejsバックエンドのみです。バックエンドでjavascriptを実行していない場合、またはモジュールシステムが配置されていない場合、Bowerはニーズによりよく適合するため、パッケージの数は関係ありません
Gerardo Grignoli

4
@GerardoGrignoli:バウアーが出ています。
Dan Dascalescu 2017

45

Bowerは単一バージョンのモジュールを維持していますが、それはあなたにあなたに合った/最適なものを選択する手助けをしようとするだけです。

Javascriptの依存関係管理:npm vs bower vs volo?

モジュールシステムがあり、ローカルで作業しているため、NPMはノードモジュールに適しています。Bowerはブラウザーには適しています。現在、グローバルスコープしかなく、操作するバージョンを非常に厳選したいからです。


4
シンドレがネストされた依存関係について話すとき、それを言及していると私は感じます。
Games Brainiac 14

5
@GamesBrainiac正解です。自分の言葉で説明すると思います。
Sagivf 14

1
@Sagivf 元の回答をここで提供した場所でもない限り、これらはあなた自身の言葉ではありません
dayuloli

4
@Sagivf 他の回答の関連する部分をコピーしても問題はありません。「自分の言葉で書いてみようかと思っただけだ」と少し言ってくれました。クレジットは、クレジットが支払われるべき場所に移動する必要があります。
dayuloli 2015年

2
なぜあなたがこの答えをそんなに選んだのか分かりません。私へのこの回答には確かに新しい情報/見解があります。
カルバン

33

私のチームはBowerから離れてnpmに移行しました。理由は次のとおりです。

  • プログラムによる使用は苦痛でした
  • バウアーのインターフェースは変わり続けた
  • 短縮形のURLなどの一部の機能は完全に壊れています
  • 同じプロジェクトでBowerとnpmの両方を使用するのは面倒です
  • bower.jsonバージョンフィールドをgitタグと同期させることは苦痛です
  • ソース管理!=パッケージ管理
  • CommonJSのサポートは簡単ではありません

詳細については、「私のチームがbowerではなくnpmを使用する理由」を参照してください。


17

http://ng-learn.org/2013/11/Bower-vs-npm/からこの有用な説明が見つかりました

一方、npmは、node.js環境で使用されるモジュール、またはnode.jsを使用して作成されたKarma、lint、minifiersなどの開発ツールをインストールするために作成されました。npmは、モジュールをプロジェクトのローカルに(デフォルトではnode_modulesに)インストールするか、グローバルにインストールして複数のプロジェクトで使用できます。大規模なプロジェクトでは、依存関係を指定する方法は、依存関係のリストを含むpackage.jsonというファイルを作成することです。npm installを実行すると、そのリストがnpmによって認識され、ダウンロードしてインストールされます。

一方、bowerはフロントエンドの依存関係を管理するために作成されました。jQuery、AngularJS、アンダースコアなどのライブラリ。npmと同様に、bower.jsonと呼ばれる依存関係のリストを指定できるファイルがあります。この場合、フロントエンドの依存関係は、デフォルトでbower_componentsというフォルダーにインストールされるbower installを実行することによってインストールされます。

ご覧のとおり、これらは同様のタスクを実行しますが、非常に異なるライブラリのセットを対象としています。


1
の登場によりnpm dedupe、これは少し時代遅れです。Mattiasの回答を参照してください。
Dan Dascalescu、2015

7

node.jsを使用する多くの人々にとって、bowerの主な利点は、javascriptではない依存関係を管理することです。javascriptにコンパイルする言語を使用している場合、npmを使用して依存関係の一部を管理できます。ただし、すべての依存関係がnode.jsモジュールになるわけではありません。JavaScriptにコンパイルするものの中には、ユーザーがソースコードを期待しているときに、JavaScriptにコンパイルして渡すことを不愉快なオプションにする、奇妙なソース言語固有の変換がある場合があります。

npmパッケージのすべてがユーザー向けのJavaScriptである必要はありませんが、npmライブラリパッケージの場合、少なくとも一部は必要です。


このnpmjsブログの投稿には、「パッケージには、ES6、クライアント側のJS、さらにはHTMLやCSSも含めて、何でも含めることができます。これらは当然JavaScriptと並んで表示されるので、そこに配置してください。」
Dan Dascalescu、2015

1
違いがあります含めることができ、および含まれるべきであるが。もちろん、何でも含めることができますが、一般的には、commonJSへの何らかのインターフェースを含める必要があります。結局のところ、これは「ノードパッケージマネージャー」です。これらの部分は、Javascriptと一緒に自然に現れることが重要です。javascriptに接線的に関連しているものの多くは、自然にそれに沿って上がらないものがあります。
jessopher、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.