ゴール
コマンドひとつでpublic/htmlに入っているファイルのリストをfileList.jsonに作る。
public/htmlにファイルが増えてもコマンドを叩けばリストが更新されるようになる。
※パッケージマネージャーはnpmを使います。
list/
│ └ fileList.json
src/
├ public/
│ ├ html
│ │ ├ index.html
│ │ ├ news.html
│ │ ├ hoge.html
│ │ └ fuga.html
│ ├ js/
│ ├ css/
│ └ images/
├ dev/
│ └ htmlList.js ←リストを作るjsはこちらに入れます。
└ base/
└ index.html
└ news.html
└ hoge.html
└ fuga.html
fileList.jsonは下記のようになるイメージ。
nameに入るのはtitleタグ内に入っている文字列の想定。
{[
{
"name": "ホーム",
"file": "/index.html"
},
{
"name": "ニュース",
"file": "/news.html"
},
{
"name": "ほげ",
"file": "/hoge.html"
},
{
"name": "ふが",
"file": "/fuga.html"
}
]}
事前準備
Node.jsをインストールしておくこと。
「とりあえず最新にしておくか」とインストールしてみたら、意外と使えないnpmパッケージとかもあるので注意です。
わからない時は推奨版をインストールしておくのがいいかと思います。
https://nodejs.org/ja/download/
早速やっていきましょうか
やることは下記の5つです。
コマンドを登録
package.jsonのscriptsに下記のように記述すればOK
"scripts": {
"htmlList": "node dev/htmlList.js",
}
これでコマンド npm run htmlList
を打てばリストが作れるようになります。
モジュールの呼び出し
fsとglobを使うので下記のように呼び出してください。他のものはいりません。
const fs = require('fs');
const glob = require('glob');
npmのglobはパターンにマッチするパス名を探してくれます。
なので、どれだけbuild配下のディレクトリが複雑になったとしても安心です。
https://www.npmjs.com/package/glob
インストールはnpm install --save-dev glob
でできます。
一覧を作るためにfsモジュールとpathモジュールを使ってfs.readdirする方法もありますが、ディレクトリが複雑になっていると少々扱いづらいので、私はglobを使った方法でやります。
fsはtitleタグの中の文字列を読むために使います。
リストにする対象のディレクトリを定義する
私はsrc/public/htmlを無条件ですべてリスト化したいので、下記のようになります。
const buildDir = 'src/public/html/**/*.html';
もしコマンドでディレクトリ指定をしたい場合は下記のとおりになります。
const targetDir = process.argv[2];
const buildDir = 'src/public/html/' + targetDir + '/**/*.html';
process.argv[2]
でコマンドの最初の引数を取得できます。
リストデータを入れるファイルを定義する
const fileListJson = 'list/fileList.json';
ファイル一覧を作ってjsonファイルに上書きをする
いっぺんにやってしまいましょう。ざっと書くと下記のようになります。
glob(buildDir, (err, files) => {
if (err) {
console.log(err);
} else {
const fileList = files.map(file => {
const fileContents = fs.readFileSync(file, 'utf-8');
const startPosition = fileContents.indexOf('<title>') + '<title>'.length;
const endPosition = fileContents.indexOf('</title>');
const name = fileContents.substring(startPosition, endPosition);
return {
'name': name,
'file': file.replace(/\/src\/public\/html/, ''),
};
});
fs.writeFileSync(fileListJson, JSON.stringify(fileList));
}
});
globのerrorの中身ですが、エラーであればオブジェクト、成功であればnullが返ってきます。
成功したら、mapでファイルリストを配列で作りましょう
mapの中のfileContentsではファイルの中身をutf-8で読み込んでいます。文字コードがないと文字化けします。
中身を取り出せたら<title>
と</title>
のあいだの文字列を取得します。
startPosition
で最初の文字のインデックス、endPosition
で最初の文字のインデックス、name
で文字を取得しています。
それができたらfileはいらない文字列を消してから、オブジェクトにしてリターンしましょう。
リストができたらfileList.jsonに上書きをします。
fs.writeFileSync
がファイルの上書きのメソッドです。
第一引数に書き込みたいファイルを指定し、第二引数に書き込みたい内容をいれます。
今回はjsonファイルへの書き込みのため、json文字列に書き換えるJSON.stringify()
をお忘れずにつけてください。
完成
これで完成です!
今回追記&新規作成をしたものをおさらいしましょう。
・package.jsonにコマンドを登録
"scripts": {
"htmlList": "node dev/htmlList.js",
}
・ファイルリストを作るためのjsを新規作成
const fs = require('fs');
const glob = require('glob');
const buildDir = 'src/public/html/**/*.html';
const fileListJson = 'list/fileList.json';
glob(buildDir, (err, files) => {
if (err) {
console.log(err);
} else {
const fileList = files.map(file => {
const fileContents = fs.readFileSync(file, 'utf-8');
const startPosition = fileContents.indexOf('<title>') + '<title>'.length;
const endPosition = fileContents.indexOf('</title>');
const name = fileContents.substring(startPosition, endPosition);
return {
'name': name,
'file': file.replace(/\/src\/public\/html/, ''),
};
});
fs.writeFileSync(fileListJson, JSON.stringify(fileList));
}
});
「できんのですが...」等なった場合はコメントいただければと思いますmm