目次

はじめに

昨今のフロントエンド開発環境では、プロジェクトディレクトリに、バンドラーやフォーマッターなどのconfigファイルがたくさんありますよね。configファイル名の形式は、.hogerc.hogerc.js.hoge.config.jsなど、さらにpackage.jsonにも書くことができたりと多種多様です。

configファイル名の形式は、ライブラリのユーザーの好みも様々で、環境変数を使ってconfigを変更するためにJSONよりもJavaScriptで設定を書きたい方や、ファイル名の先頭にピリオド(.)をつけて、ファイル名でソートした時にconfigファイルが集まるようにしたい方など、色々な考え方があります。そのため、configファイル名は一つに決まっているよりはある程度ユーザーに選択肢がある方が好ましいと思っています。

ただし、configファイル名やJSONやYAMLなどのフォーマットなど多くのパターンを自力でサポートするのは、なかなか大変な作業です。これらを簡単にサポートするにはどうしたらいいか気になりいろいろと調べた結果、prettierstylelintでも使用されている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.jshoge.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でさばくのが楽でよさそう
  • オプションでファイル名やフォーマットも柔軟に変えることができる