at backyard

Color my life with the chaos of trouble.

Node.jsでローカルのJSONファイルをrequireを使って読み込む際の気をつけるポイント

下書きに放り込んだまま忘れていたので、ポスト。

Node.jsのrequireを用いてJSONファイルを読むときに気をつけること

Node.jsのrequireを用いてJSONファイルをそのまま読み込むことができる。

const json = require('./sample.json');
consle.log(json);

これは一見便利だが、例えば下記のような処理を実行した場合に(個人的に)予想外の動きをする。

requireを使ってJSONファイルを読み込む際に気をつけること

読み込むJSONファイル

{
  "id": "1",
  "name": "test"
}

実行するコード。

const a = async () => {
  const json = require('./sample.json');
  json.age = 20;
  console.log({json});
}

const b = async () => {
  const json = require('./sample.json');
  console.log({json});
}

(async () => {
  await a();
  await b();
})();

こちらを実行すると、関数bのほうの出力結果にも age に関する値が含まれている。 つまり関数a内での処理結果の状態がそのまま関数bにも持ち込まれている形となる。

fs.readFile を用いてJSONファイルを読み込んだ場合、こうはならない。 下記の場合、関数bには age という項目は含まれない。

const fs = require('fs').promises;

const a = async () => {
  const json = JSON.parse(await fs.readFile('./sample.json', 'utf8'));
  json.age = 20;
  console.log({json});
}

const b = async () => {
  const json = JSON.parse(await fs.readFile('./sample.json', 'utf8'));
  console.log({json});
}

(async () => {
  await a();
  await b();
})();

一度requireで直接読み込まれたJSONのデータはメモリ上でそのまま確保され続けていて、別の処理で読み込んだ際には新たに作られるわけではないのだろうか?
そのうちNode.jsのソースコードを読んで確かめてみようと思う。