lodashというユーティリティライブラリがあります。lodashは便利な関数をたくさん提供しています。たとえば配列をシャッフルするshuffle()
や、配列の差をとるdifference()
などが挙げられます。
lodashは300個以上の関数を提供しています。しかし、実際に使うのはそのうちせいぜい10個です。コードサイズが大きくなってしまうのはJavaScript的に大罪です。そこで、必要な関数だけピックアップする方法が提供されています。それがタイトルにもあるrequire('lodash/zipWith')
といった書き方です。
今回はどうしてそれで300を超える関数が読み込めるようになっているのか解説します。
lodashモジュールの様々な読み込み方
lodashは以下のように複数の読み出し方に対応しています。
const {zipWith} = require('lodash'); // lodashのすべてが読み込まれてしまっている const {zipWith} = require('lodash/array'); // lodashのうち配列操作系だけ読み込む const zipWith = require('lodash/zipWith'); // 関数をピンポイントで読み込む
ES Modulesを使う書き方もできます(node_modules/
配下を参照するので、Node.jsでのみ動作します)。
import * as _ from 'lodash'; import * as lodashArray from 'lodash/array'; import zipWith from 'lodash/zipWith';
では、どうしてこのような読み込み方ができるのでしょうか?実際にインストールしたパッケージを見てみます。
なんと631個もJavaScriptファイルが置かれています!そして、それぞれ関数に対応したファイル、arrayに対応したファイルがあります。
つまり、require('lodash/array')
ではlodashパッケージ内にあるarray.js
が読み込まれます。同様にrequire('lodash/zipWith')
ではzipWith.js
が読み込まれます。
仕様ではどうなっているのか?
Node.jsのドキュメントのModulesページを見てみます。
どうやら、require('example-module/path/to/file')
は./node_moduels/example-module/path/to/file
と同様のようです(現在のディレクトリのnode_modules
になければ見つかるまで親ディレクトリを辿っていくようです)。
つまり、上のrequire('lodash/array')
はドキュメントで保証されている動作らしいです。
これって名前空間なのでは?
このrequire('lodash/array')
という書き方、lodashという名前空間のarrayを読み込むと見えませんか?実際の動作も名前空間にみえます。非常に面白いですね。
ただ、実際にコレをやっているパッケージをあまり見ない気がします。そもそもやる必要があるパッケージが少ないというのがありますが。