Edited at

イマドキのnpmでは何を配布すべきか


はじめに

みなさん、npmでパッケージ公開してますか?

自分はこれまでいくつか公開したんですが、ここ最近「モダンに使ってもらうために何をパッケージングして配布すべきか」を見つめ直したので、自分なりの結論を語らせていただきたいと思います。


CommonJSのモジュール

Node.js環境でモジュールとして使用されるために、CommonJS形式で実装したモジュールは現状必須かなと思います。

CommonJSモジュールをpackage.jsonのmainフィールドに設定すると、require("パッケージ名")で利用可能になります。


配布例

CommonJS形式で定数hogeをexport

// hoge.js

exports.hoge = "HOGE";

package.jsonのmainフィールドに設定

{

"name": "パッケージ名",
"main": "hoge.js"
}

これで、Node.js環境なら以下のように使えます

const { hoge } = require("パッケージ名");


ECMAScriptのモジュール

webpackなどでバンドルして使われる想定の場合、ES Modulesとして実装したコードも配布した方が良いと思います。

webpackやRollup等のモダンなモジュールバンドラーでは、package.jsonのmoduleフィールドに設定されているコードをES Modulesとして優先的に読み込むようになっていて、その場合はTreeShakingによるコード量の削減が期待できます。


配布例

ES2015形式で定数hogeをexport

// hoge.js

export const hoge = "HOGE";

package.jsonのmoduleフィールドに設定

{

"name": "パッケージ名",
"module": "hoge.js"
}

バンドル前のJavaScriptで以下のように使えます

import { hoge } from "パッケージ名";


TypeScriptの型定義ファイル

こちらのアンケートによるとTypeScriptは約半数のエンジニアが使ったことがあり、AltJSでは現状一番人気と言えるのかなと思います。

そんなTypeScriptでは型定義ファイルが提供されていないモジュールは使いづらく、型定義の無いモジュールがTypeScriptのプロジェクトに採用されることは滅多にないんじゃないでしょうか。

有名どころのパッケージは@typesでサポートされていたりしますが、いざ使ってみると最新版の定義が反映されていなかったりして辛い時があります。

そういう訳で、イマドキのnpmなら型定義も一緒に配布してあげた方が親切だしメンテもしやすいんじゃないかなと思います。

TypeScriptの型定義ファイルは、package.jsonのtypesフィールドに設定しておけばOKです。

詳しくは公式ドキュメントで

https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html


ブラウザ用にバンドルしたコード

バンドルしてブラウザで使われる想定のモジュールの場合、あらかじめバンドルしたコードも一緒に配布することをオススメします。

そうすると、npm install xxxせずともunpkg.com経由でダウンロードできるので、CodePenなどのサービスでサクッと試してもらうことができます。

例えばpng.esでは以下のURLで、npmに配布中のバンドル済みコードを取得できます。

https://unpkg.com/png.es@0.4.0/dist/browser/png.min.js

なのでHTMLのscriptタグで読み込んで使用できます。

See the Pen GPpbgK by zprodev (@zprodev) on CodePen.



バンドルしたECMAScriptのモジュール

モダンなブラウザは概ねESModulesに対応済みです。

上のブラウザ用バンドルコードと同様の理由で、ECMAScriptモジュールもバンドルして提供すると簡単に試してもらうことができます。

png.esでは以下のURLでバンドル済みECMAScriptモジュールを配布しています。

https://unpkg.com/png.es@0.4.0/dist/esm/png.min.js

CodePenのJavaScriptはtype="module"設定されているため、すぐにESModulesを使用できます。

See the Pen Ydyobw by zprodev (@zprodev) on CodePen.


さいごに

触ったことないけどモダンと噂のVue.jsを覗いてみました。

スクリーンショット 2018-12-13 20.39.34.png

devとかprodとか分けて色々配布されてますね。親切。

package.jsonの配布物っぽいフィールドはこんな感じです。

  "main": "dist/vue.runtime.common.js",

"module": "dist/vue.runtime.esm.js",
"typings": "types/index.d.ts",
"unpkg": "dist/vue.js",

typingstypesは同じ役割なので、CommonJS、ESModules、TypeScriptの型定義を配布するのは一緒ですね。

unpkgunpkg.com用なんだろうか・・・?