ルートディレクトリにnext.config.js
を作る
このファイルは通常の Node.js モジュールであり JSON ファイルではありません。 Next.js サーバーとビルドフェーズで使用され、ブラウザのビルドには含まれません。
next.config.js
const fs = require('fs');
const path = require('path');
module.exports = (phase, { defaultConfig }) => {
const POSTS_PATH = path.join(process.cwd(), 'posts');
const PUBLIC_PATH = path.join(process.cwd(), 'public');
// 同階層内の画像を取得
const files = fs.readdirSync(POSTS_PATH);
// filesから画像だけ抽出
const images = files.filter((f) => (f.match(/^\w+\.(jpeg|jpg|png|gif|webp)/)))
// 画像をpublicフォルダにコピー
images.forEach(image => (fs.copyFileSync(path.join(POSTS_PATH, image), path.join(PUBLIC_PATH, image))))
return {
/* ここにオプション設定を書きます */
};
};
このようにすることによってビルド時にpostsディレクトリの画像がpublicにコピーされる
mdxファイルで画像を呼び出す時
![mdx-image](/1.png#100_100)
のようにすることができる
このままだとposts以下にディレクトリを作った時、その中のファイルは読み込まれない。そこを読み込むようにしたい。
const fs = require('fs')
const path = require('path')
module.exports = (phase, { defaultConfig }) => {
const POSTS_PATH = path.join(process.cwd(), 'posts')
const PUBLIC_PATH = path.join(process.cwd(), 'public')
// コメントアウト↓
// // 同階層内の画像を取得
// const files = fs.readdirSync(POSTS_PATH)
// // filesから画像だけ抽出
// const images = files.filter((f) => (f.match(/^\w+\.(jpeg|jpg|png|gif|webp)/)))
// // 画像をpublicフォルダにコピー
// images.forEach(image => (fs.copyFileSync(path.join(POSTS_PATH, image), path.join(PUBLIC_PATH, image))))
// 追加↓
// 再帰的に画像をpublicフォルダにコピー
CopyFilesRecursively(POSTS_PATH, PUBLIC_PATH)
return {
/* ここにオプション設定を書きます */
}
}
// 追加↓
/**---------------------------------------
* ・サブフォルダ下位すべての画像ファイル列挙
*----------------------------------------
* @param {string} srcpath コピー元のパス
* ・同期
* ・戻り値にはposts/以下のパスが入る
* @return 取得したファイル、ディレクトリの{path:相対パス, isDir:ディレクトリか}を配列で返す
*/
const readSubDirSync = (srcPath) => {
let result = [];
const readTopDirSync = ((srcPath) => {
let items = fs.readdirSync(srcPath)
items = items.map((itemName) => (path.join(srcPath, itemName)))
items.forEach((itemPath) => {
// posts/以下のフォルダ、ファイル名だけ
const relativePath = itemPath.match(/.+\/posts\/(.+)/)
result.push({path: relativePath[1], isDir: fs.statSync(itemPath).isDirectory()})
//再帰処理
if (fs.statSync(itemPath).isDirectory()) readTopDirSync(itemPath)
})
})
readTopDirSync(srcPath)
// resultからディレクトリ、画像だけ抽出
const output = result?.filter((obj) => {
return obj.path.match(/^\S+\.(jpeg|jpg|png|gif|webp)/) || obj.isDir === true
})
return output
}
/**
* 指定したパス配下のフォルダ、ファイルを同じ構造で再帰的にコピーします。
* コピー先のディレクトリが存在しない場合、フォルダが作成され、その中にコピーします。
* 権限不足や容量不足の場合、例外を検知し停止します。
* @param {string} srcPath コピー元のパス
* @param {string} destPath コピー先のパス
*/
const CopyFilesRecursively = ((srcPath, destPath) => {
if (!fs.existsSync(destPath)) fs.mkdirSync(destPath, { recursive: true })
let targetList = readSubDirSync(srcPath)
targetList.forEach(node => {
let newPath = `${destPath}/${node.path}`
if (node.isDir) {
if (!fs.existsSync(newPath)) fs.mkdirSync(newPath)
} else {
fs.copyFileSync(`${srcPath}/${node.path}`, newPath)
}
})
})
これでフォルダもコピーできるようになった
参考