読者です 読者をやめる 読者になる 読者になる

オフトゥン大好き

惰眠系プログラマの作業ログで( ˘ω˘ ) スヤァ…

言語ごとのモジュール・エコシステム事情

プログラミング Ruby Perl Node.js JavaScript golang Elixir Erlang

ダンな言語には標準でパッケージマネージャが付属することが少なくない。 これは依存関係を洗い出して開発やランタイムに必要なパッケージを自動で補完してくれるうえ、自分が作成したライブラリやアプリケーションを公開する際にも便利なユーティリティとして機能する。

いつ頃からこのようなツール群が一般的になったのかはわからないが、最近触れる機会のある言語はもれなくこの恩恵に預かっていて、それぞれの言語についてエコシステム事情が気になったので調べてみた。 触ったことがあるもの以外はあまり詳しくは書けないし間違っているかもしれない。

Ruby: RubyGems

RubyGems.org | your community gem host

数多くの言語の中でも活発なコミュニティを有するRubyRubyGemsというエコシステムが存在する。gemやbundlerといったツールを用いて開発や実行に必要なパッケージをインストールする。依存するモジュールはGemfileというファイルに記述し、インストールするたび環境ごとの差異をなくすためGemfile.lockというファイルを生成してgemのバージョンや取得先を固定する。

JavaScript: npm

npm

Node.jsから生まれたモジュールシステムであり、当初はサーバサイドJavaScriptであるNode.js専用のパッケージマネージャだったため、フロント側では別にbowerというマネージャが発達していた。しかし、browserifyやwebpackなどのパッキングツールの発展、サーバとフロントの両方に対応したisomorphicなライブラリの増加で近年ではbowerを投げ捨てて、npmひとつで全てを完遂するのが主流になりつつある。

Perl: CPAN

CPANはComprehensive Perl Archive Networkの略でPerlのパッケージレジストリである。このレジストリ自体は現代的なエコシステムが発達する以前から存在しており、古くはtarアーカイブをダウンロードしてインストールしたり、OS標準のパッケージマネージャを使ってモジュールをインストールしたりしていた。今では言語用のモジュールシステムの流れに乗りCPANから依存モジュールを自動で展開するツールが公開されている。自作のモジュールを公開するにはPAUSEと呼ばれる開発者用のアップロードサーバに登録する必要がある。(しかしこのPAUSE、登録申請をどうやら人力で確認しているらしく時間がかかる)

Perl6: Perl 6 Modules

Perl 6 Modules Directory

まだ発展途上ではあるが、パッケージマネージャにはpandaというものがありmodule.perl6.orgに登録されているモジュールをインストールすることができる。 CPANのようなレジストリサーバは存在しておらずecosystem GitHubリポジトリに自らのモジュールリポジトリにあるメタデータファイルパスを追記することで公開される。

PHP: Packagist

Packagist

結構前にCakePHP 2.x系を使った開発案件に携わっていたことがあるが、その頃のPHPのパッケージ管理事情は酷いものだった。そもそもまともなパッケージマネージャは存在していなかったし、エラーの原因がパッケージのバージョンなのか言語のバージョンなのかも判別が難しい状態だった。今ではcomposerというパッケージマネージャを用いるのが主流になり、ようやくこうした状況も改善された。composerはPackagistというレジストリを参照しているため、公開する際はここにモジュールのURL(GitHubなど)をsubmitする。

Python: PyPI

PyPI - the Python Package Index : Python Package Index

PythonにはPyPIというリポジトリが存在していて、インストーラとしてはeasy_installとpipがよく使われるようだ。

参考記事:Python パッケージ管理技術まとめ (pip, setuptools, easy_install, etc) (16/10/8閲覧)

Go: gopkg.in, GitHub, BitBucket, ...

Go言語はバージョン管理システムリポジトリをそのままパッケージとして取り込むため、特定のモジュールレジストリは存在しない。そのためimportは標準ライブラリ以外は以下のような指定になる。

import (
  "github.com/hoge/huga"
  "bitbucket.org/hoge/huga"
)

go自体にパッケージマネージャは統合されているが、go getはデフォルトで最新のリビジョンを落としてくるため、バージョンを固定するには別途godepなどのツールを使用するかgopkg.inでバージョンを含んだURLを指定する必要がある。

Java: Maven

The Central Repository Search Engine

JavaにはMavenというツールがあり、Maven Central Repositoryというリポジトリからパッケージを取得している。最近ではGradleというビルドツールを使うことが増えているが、こちらでもMavenリポジトリを利用することができる。

Erlang, Elixir: hex

Hex

Erlangと同じくErlang VMで動作するElixirにはhexというモジュールシステムがある。Erlangではrebar, Elixirではmixというツールを用いてパッケージマネージングを行う。

その他

CやC++など古くから存在するネイティブ言語にもあるかと思って調べてみたら一応見つかった。

C/C++ Open Source Package Manager

認知度も低く、まだ流行っているとは言い難い状況だが、普及すれば特に複雑なC/C++のライブラリ依存解決も楽になりそうだ。

参考記事:C/C++ のパッケージマネージャーである conan を使ってみた - Secret Garden(Instrumental) (16/10/8閲覧)

まとめ

  • 企業が運営しているもの、コミュニティが運営しているもの、特定のレジストリを持たないものなどそれぞれ微妙に異なるが、言語ごとにエコシステムが存在している。
  • 古い言語でも後からパッケージマネージャが開発されており、以前の管理方法との統合が図られている。