1. ホーム
  2. node.js

[解決済み] node.js require()キャッシュ - 無効化可能か?

2022-03-14 19:27:51

質問

node.jsのドキュメントより。

<ブロッククオート

モジュールは、最初にロードされた後にキャッシュされます。これは、(とりわけ)require('foo')を呼び出すたびに、同じファイルに解決されるのであれば、まったく同じオブジェクトが返されることを意味します。

このキャッシュを無効にする方法はありますか?例えば、ユニットテストでは、各テストが新しいオブジェクトで動作するようにしたいのですが。

解決方法は?

循環的な依存関係がある場合でも、問題なく常に安全に require.cache のエントリを削除することができます。なぜなら、削除するときは、モジュールオブジェクト自体ではなく、キャッシュされたモジュールオブジェクトへの参照を削除するだけだからです。循環的依存関係がある場合、このモジュールオブジェクトを参照しているオブジェクトがまだ存在するため、モジュールオブジェクトはGCされません。

があるとします。

スクリプトa.jsです。

var b=require('./b.js').b;
exports.a='a from a.js';
exports.b=b;

スクリプトb.jsです。

var a=require('./a.js').a;
exports.b='b from b.js';
exports.a=a;

をすると

var a=require('./a.js')
var b=require('./b.js')

を得ることになります。

> a
{ a: 'a from a.js', b: 'b from b.js' }
> b
{ b: 'b from b.js', a: undefined }

ここで、b.jsを編集してみると。

var a=require('./a.js').a;
exports.b='b from b.js. changed value';
exports.a=a;

と実行します。

delete require.cache[require.resolve('./b.js')]
b=require('./b.js')

を得ることになります。

> a
{ a: 'a from a.js', b: 'b from b.js' }
> b
{ b: 'b from b.js. changed value',
  a: 'a from a.js' }

===

上記は、node.jsを直接実行する場合に有効です。しかし、独自のモジュールキャッシングシステムを持つツール、例えば ジェスト というのが正しい記述になります。

jest.resetModules();