npmで名前空間を持ったモジュールを公開する方法(scoped modules)
npmにモジュールを公開することは多くなってると思いますが、今までのnpmだと名前は早い者勝ちでした。
最近npm Private Modulesというprivateで扱えるモジュールを有料でサポートしましたが、これはscoped modulesをprivateで扱う時だけ有料でpublicで公開する時は無料で行えます。
scoped modulesというのは、@username/project-name
という感じで、@ユーザー名がパッケージ名に入るので異なるユーザー間では重複しません。
公開手順
実際にscoped modulesをpublicに公開する手順としては、
npm init --scope=<npmユーザ名>
- パッケージの名前が
@<npmユーザ名>/パッケージ名
になる - 手動で書き換えても別に問題ない
- パッケージの名前が
- 適当に開発
npm publish --access=public
- またはpublishConfigで
public
に設定(こちらの方が宣言的)
- またはpublishConfigで
するだけです。
簡単に書くとscoped modulesとして作って、公開する時はnpm publish --access=public
とするだけです。(デフォルトが--access=restricted
であるため明示する必要がある。必要なのは最初に公開する時のみ)
pacakge.json
のpublishConfigでpublic
に設定してある場合は、npm publish
の--access
オプションは不要です。
...
"publishConfig": {
"access": "public"
}
...
こうして公開したモジュールは
npm install @<npmユーザ名>/パッケージ名
という感じで、普通のモジュールと同様にインストールできます。
以下の記事で書いてたpublishのパターンも少し更新しておきました。
公開例
実際に適当なものを作ってみました。
$ npm install @azu/github -g
という感じでインストールできることがわかると思います。 npm version 2.xが必要ですが、Node 0.12を使っていれば勝手に入ってるはず。
npm install -g npm
で、npmだけのアップデートも可能です。
おわりに
scoped modulesを使うことで、npmでも名前空間っぽいものが扱えるようになりました。
scoped modulesであれば名前の重複などを気にしなくてよくなるのはいい気がします。
これの問題としては、周辺のツールがまだ未対応であったりすることがあります。
例えば、@myorg/mypackage
という名前のモジュールをインストールすると以下のような配置でnode_modules以下にインストールされます。
node_modules
├── @myorg
│ └── mypackage
│ └── package.json
├── browserify
│ └──package.json
├── del
│ ├── index.js
│ └──package.json
....
そのため、ディレクトリが一つ深くなって再帰的に探索していないツールなどはscoped modulesを無視してしまう事があります。
具体的にはtsd link
などはそういうバグがあったりしました。
追記(2019-01-24): publishConfigについてを追加
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。