Help us understand the problem. What is going on with this article?

Webpackでフォルダ内の全ファイルを一気にrequireする

More than 1 year has passed since last update.

Webpackには、CommonJSのrequireよりも強力な、依存関係処理機能があります。

ふつうのrequireとWebpack

npmで入れたライブラリを指定する場合にしても、自分で作ったファイルを呼び出す場合にしても、ほとんどの状況でrequireすべきファイルはソースコードの時点で決まっているものです。

Webpackでは、リテラルでrequireを行った場合、コンパイル後にはrequireの引数が、モジュールの番号に置き換わっています。

動的なrequireとコンテキスト

ただ、CommonJS Modulesの仕様でも、requireが取る引数は一定の書式の「文字列」となっているだけで、もちろんリテラル限定なんてことはありません。任意の文字列を指定することができます。

このような場合、ソースコードの時点では何をrequireするか決まらないので、固定的にコンパイルすることはもちろん不可能です。Webpackでは、requireするモジュールが決まりきらないコードを発見すると、「requireコンテキスト」を生成します。

requireコンテキストは、ソースコードから判別できる接頭辞・接尾辞(フォルダ位置・拡張子など)からできるだけ絞り込んだ上で、候補になりうるすべてのモジュールを用意した上で、最終的にrequireを呼び出した文字列で実際にrequireするものを決定する、というような流れになっています。

コンテキストを自分で作る

上で述べた「requireコンテキスト」は、Webpackが自動で用意するだけではなく、require.contextを呼び出すことで、自分で作ることもできます。

const context = require.context(directory, useSubdirectories = false, regExp = /^\.\//)

引数の意味は次のようになっていますが、コンパイル時に解決しないといけないため、すべてリテラルである必要があります。

  • directory…どこのディレクトリの中身をrequireの対象とするか
  • useSubdirectories…対象のディレクトリ直下だけ拾うならfalse、以下の全ディレクトリを対象にするならtrue
  • regExp…対象になるファイルが満たすべき条件を書いた正規表現(/\.js$/のように、拡張子指定に使うと便利です)

コンテキストの操作

コンテキストを作っただけでは、requireは行われません。このcontextは、以下のようなものからなっています。

  • context(パス)…指定されたパスのモジュールをrequireする(もちろん、コンテキストになければ失敗)
  • context.resolve(パス)…指定されたパスをモジュール番号に変換する(もちろん、コンテキストになければ失敗)
  • context.keys()…コンテキストに含まれるパスの配列を返す
  • context.id…コンテキスト自体のモジュール番号

実用例

Riot.jsとWebpackを組み合わせる場合、riot/tag-loaderがあるので、これを使えば.tagファイルもrequireできますし、require('riot')で呼び出されるRiot本体に、requireした時点でタグとして登録されます。

Riotのタグをセットする側でriot.mount('*')のようにするのであれば、requireしたものを自分で保存しておく必要もない、ということになります。ということで、タグは「ただrequireしておくだけでいい」ということになります。

このような場合、以下のコードで一括requireできます。

function allRequire(context){
  context.keys().forEach(context);
}

allRequire(require.context('./path/to/tags/', true, /\.tag$/))

forEach(context)が直感的ではありませんが、context自体が「モジュールのパスを受け取ってrequireする関数」なので、forEachが投げてくる「1つ目が値」というパターンにぴったりなのです。

参照

jkr_2255
qiitadon
Qiitadon(β)から生まれた Qiita ユーザー・コミュニティです。
https://qiitadon.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした