0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Node.jsでファイルを読み込んであれこれする時の備忘録

Last updated at Posted at 2023-01-03

ゴール

コマンドひとつでpublic/htmlに入っているファイルのリストをfileList.jsonに作る。
public/htmlにファイルが増えてもコマンドを叩けばリストが更新されるようになる。
※パッケージマネージャーはnpmを使います。

ディレクトリ(public/htmlはbaseをビルドしたものが入る前提)

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タグ内に入っている文字列の想定。

fileList.json
{[
    {
        "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つです。

  1. コマンドを登録
  2. モジュールの呼び出し
  3. リストにする対象のディレクトリを定義する
  4. リストデータを入れるファイルを定義する
  5. ファイル一覧を作ってjsonファイルに上書きをする

コマンドを登録

package.jsonのscriptsに下記のように記述すればOK

package.json
  "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';

もしコマンドでディレクトリ指定をしたい場合は下記のとおりになります。

コマンドでsrc/public/html/spのみを指定したい場合
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にコマンドを登録

package.json
  "scripts": {
    "htmlList": "node dev/htmlList.js",
  }

・ファイルリストを作るためのjsを新規作成

src/dev/htmlList.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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?