はじめに
みなさん、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を覗いてみました。
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",
typings
とtypes
は同じ役割なので、CommonJS、ESModules、TypeScriptの型定義を配布するのは一緒ですね。
unpkg
はunpkg.com用なんだろうか・・・?