Node.js製ライブラリのconfigはcosmiconfigで実装するのがよさそう
はじめに
昨今のフロントエンド開発環境では、プロジェクトディレクトリに、バンドラーやフォーマッターなどのconfigファイルがたくさんありますよね。configファイル名の形式は、.hogercや.hogerc.js、.hoge.config.jsなど、さらにpackage.jsonにも書くことができたりと多種多様です。
configファイル名の形式は、ライブラリのユーザーの好みも様々で、環境変数を使ってconfigを変更するためにJSONよりもJavaScriptで設定を書きたい方や、ファイル名の先頭にピリオド(.)をつけて、ファイル名でソートした時にconfigファイルが集まるようにしたい方など、色々な考え方があります。そのため、configファイル名は一つに決まっているよりはある程度ユーザーに選択肢がある方が好ましいと思っています。
ただし、configファイル名やJSONやYAMLなどのフォーマットなど多くのパターンを自力でサポートするのは、なかなか大変な作業です。これらを簡単にサポートするにはどうしたらいいか気になりいろいろと調べた結果、prettierやstylelintでも使用されているcosmiconfigを使うのがよさそうだったので紹介します。
cosmiconfigを使ってみる
cosmiconfigをインストール
cosmiconfigはnpmでインストールできます。npmやyarnでインストールしましょう。
npm install cosmiconfig動作確認用のconfigファイルを作る
動作確認用に.hogerc.jsというファイル名で以下のようなファイルを用意します。
// .hogerc.js
module.exports = {
name: 'hoge'
}configを読み込むための処理を書く
.hogerc.jsと同じディレクトリにindex.jsという名前で次のファイルを作成します。
// index.js
const { cosmiconfig } = require('cosmiconfig')
const moduleName = 'hoge'
const main = async () => {
const explorer = cosmiconfig(moduleName)
const config = await explorer.search()
console.log(config)
}
main()node index.jsを実行すると、ターミナルに次のように表示され、.hogerc.jsが取得できていることがわかります。
{
"config": {
"name": "hoge"
},
"filepath": "/Users/user-name/project-dir/.hogerc.js"
}複雑な処理を書かなくても簡単にconfigを取得できることがわかりましたね。configファイルの検索はcosmiconfigでやってくれるので、この状態で.hogerc.jsをhoge.config.jsにリネームしても同じようにconfigを取得することができます。
よく使用しそうなカスタマイズ方法も紹介します。
searchPlacesオプションで検索対象のconfigファイル名を指定する
cosmiconfigはsearchPlacesオプションを使用して、検索するconfigファイル名を指定することができます。デフォルトは次のようになっているので、先ほど作った.hogerc.jsもデフォルトで読み込むことができます。
[
'package.json',
`.${moduleName}rc`,
`.${moduleName}rc.json`,
`.${moduleName}rc.yaml`,
`.${moduleName}rc.yml`,
`.${moduleName}rc.js`,
`${moduleName}.config.js`,
]例えば、次のようにsearchPlacesオプションを指定すると、先ほど作った.hogerc.jsは検索対象から外れ、hoge.config.jsまたはhoge.settei.jsのみが読み込まれます。
// index.js
const { cosmiconfig } = require('cosmiconfig')
const moduleName = 'kimulaco'
const main = async () => {
const explorer = cosmiconfig(moduleName, {
searchPlaces: [
`${moduleName}.config.js`,
`${moduleName}.settei.js`
]
})
const config = await explorer.search()
console.log(config)
}
main()loaderオプションで、ファイルのフォーマットを変更する
cosmiconfigはloadersオプションを使用して、configファイルのフォーマットを変更することが可能です。例えば、.hogercなどの拡張子のないconfigファイルでは、JSONで書くのかYAMLで書くのかなどがライブラリによって異なると思います。cosmiconfigのデフォルトでは、拡張子のないconfigファイルはYAMLとして扱われますが、JSONに変えたい場合は以下のようにloaderを指定します。
// index.js
const { cosmiconfig, defaultLoaders } = require('cosmiconfig')
const moduleName = 'kimulaco'
const main = async () => {
const explorer = cosmiconfig(moduleName, {
loaders: {
noExt: defaultLoaders['.json']
}
})
const config = await explorer.search()
console.log(config)
}
main()基本的なフォーマットであれば、defaultLoadersを使って指定することができます。独自な記法を使用したり、cosmiconfigがサポートしていないフォーマットのconfigを使用する場合は、既存のパッケージや自作のloaderを指定しましょう。
まとめ
- ライブラリを開発するときのconfigはcosmiconfigでさばくのが楽でよさそう
- オプションでファイル名やフォーマットも柔軟に変えることができる