require-dirでモジュールを一括require【Node.js】
April 08, 2020
require-dir は指定されたディレクトリのjsモジュールをまとめてrequireしてくれる便利なモジュールです。
インストール
npm install require-dir
# yarn を使う場合
yarn add require-dir
ディレクトリ構成例
root
├ index.js
└ modules
├ a.js
├ b.js
├ c.js
└ other/index.jsから require-dir を使ってmodules内のモジュールをrequireします。
サンプルとして other というディレクトリを入れてありますが、 require-dir は .js ファイル以外を無視してくれます。
a.js
module.exports = function () {
...
}各jsファイルの中身は関数をexportする単純なものです。
基本的な使い方
index.js
const requireDir = require('require-dir')
// 読み込みたいモジュールがあるディレクトリのパスを入れる
const modules = requireDir('./modules')
// { a: [Function], b: [Function], c: [Function] }.js を除いたファイル名がキーとなって、requireされたオブジェクトが取得できます。
どんな時に使うの?
モジュールを一括でrequireしたい時はもちろんですが、
ファイル名がキーとなるので、ExpressのRouterなどに使うとメンテナンスのしやすさやコードの見通しが良くなります。
Expressでの使用例
ディレクトリ構成
root
├ app.js
└ routes
│ a.js
└ b.jsa.js
const router = require('express').Router()
router.get('/' (req, res) => {
res.send('ok')
})
module.exports = routerapp.useに渡す
app.js
const express = require('express')
const app = express()
const requireDir = require('require-dir')
// routesにあるRouterを全てrequireする
const routes = requireDir('./routes')
// キーを元にしたした配列を作る
Object.keys(routes).forEach(fileName => {
// ファイル名をルート名とする
// forEachを使い app.use に router を渡す
app.use(`/${ fileName }`, routes[fileName])
})
const listener = app.listen(process.env.PORT || 3000, () => {
console.log("listening on port " + listener.address().port);
});ひとつずつrequireする必要がないので楽です。
さらに!
ルートごとにディレクトリで管理したいと思うことがあるはずです。
例えばこういうディレクトリ構成 ↓
root
├ app.js
└ routes
├ a
│ └ index.js
└ b
└ index.jsそんな時は require-dir にオプションを与えます。
const routes = requireDir('./routes', {
recurse: true
})
// {
// a: { index: [Function: router] },
// b: { index: [Function: router] }
// }このように、指定したディレクトリの中まで参照してくれるようになります。
上記の方法に合わせて書き換える
app.js
const express = require('express')
const app = express()
const requireDir = require('require-dir')
const routes = requireDir('./routes', {
recurse: true
})
Object.keys(routes).forEach(fileName => {
// routes[filename] の中の index を指定する
app.use(`/${ fileName }`, routes[fileName].index)
})
const listener = app.listen(process.env.PORT || 3000, () => {
console.log("listening on port " + listener.address().port);
});これでルートが無限に増えても安心です。
残念な点・ …url/:id のようなルートパラメーターが設定できない。
・ ミドルウェアを挟みたい場合はforEach内で分岐する必要がある。