webpack で特定ディレクトリ以下のファイルを全てインポートして配列にする
やりたいこと
src
├─ template
| ├─ a.txt
| ├─ b.txt
| └─ c.txt
└─ templates.ts
こういうディレクトリ構造のとき、template フォルダのファイルを
[
{
name: 'a',
value: 'a.txtの中身'
},
{
name: 'b',
value: 'b.txtの中身'
},
{
name: 'c',
value: 'c.txtの中身'
}
]
みたいな形で取り出したい。
方法
1. パッケージのインストール
raw-loader
... webpack で txt ファイルを読み込むため@types/webpack-env
... この後使用するrequire.context
の型定義を読み込むため
npm i -D raw-loader @types/webpack-env
2. webpack.config.js
に raw-loader
を設定
読み込ませたい拡張子が複数ある場合は /\.txt$/
のところを変更する。
この方法で読み込む場合、TypeScript では必要だった declare module '*.txt'
のような宣言も必要無さそう。
// webpack.config.js
module.exports = {
/* 略 */
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader'
},
/* 追加 ここから */
{
test: /\.txt$/,
use: 'raw-loader'
}
/* 追加 ここまで */
]
},
/* 略 */
};
3. 読み込み処理の記述
require.context()
に読み込むフォルダへの相対パスを渡す。
context.keys()
でそのフォルダ以下のファイルの相対パスが配列で渡されるので、Array.map()
で欲しい形に変える。
// templates.ts
interface Files {
name: string;
value: string;
}
const context = require.context('./template');
const templates: ReadonlyArray<Files> = context.keys().map(path => {
return {
// 拡張子を省いたファイル名のみを抜き出す
name: path.match(/([^/]*)(?:\.([^.]+$))/)[1],
// ファイルの中身をstringで読み込み
value: context(path)
};
});
export default templates;