Webpack / Electronでモジュールの再リロードが出来なくて困った件


急いでいる人向け

delete global.require.cache[global.require.resolve('moduleName')];
let module = global.require('moduleName');

概要

とある残念なサードパーティモジュールがあり、そいつは関数式を返すのではなく、
Functionオブジェクトを返してきた。

もちろん、そのオブジェクトのプロパティに値を詰めたりして使っていたのだが、
初期化して再度そのオブジェクトを使う場面が出てきやがった。

require.cacheをdeleteして、再度requireしたら、
直近のオブジェクトに酷似したものを返してきたんだ。

それはもう数日かけて、眠い目を擦らせながら調べたものさ。

実験 & 調査

[1]本当にキャッシュが消えていないのか

console.log(require.cache);
delete require.cache[require.resolve('moduleName')];
console.log(require.cache);

これだと対象のモジュールのキャッシュは消えていなかった。

[2]本当にキャッシュはあるのか

console.log(require.cache[require.resolve('moduleName')]);
delete require.cache[require.resolve('moduleName')];
console.log(require.cache[require.resolve('moduleName')]);

しかし、これだとdelete後はundefinedになっていた。
じゃあrequireしたオブジェクトが過去のオブジェクトと酷似している理由はなんだ!?
require.cacheからとってきているんじゃないのか!?

[調査結果]
nodejsのrequireとは違う動きしてるんじゃないか・・?

解決策

global.requireを使いなさい。

requireは、webpack_require()に変換されているらしく(未確認)、
それでうまくいかないらしい。

後日談

global.requireとやらがそもそも知らなかったので調べて見たものの、
これといった資料が見当たらない・・・。

とりあえず中をのぞいてわかったことは、キーをモジュールのフルパスで持っているということだ。

何かいい情報が載っている記事がありましたら、誰か教えてください。