2011-07-13 6 views
42

モジュールを使用した後でモジュールをアンロードする方法があるのが不思議です。私はコードを大量に持っているモジュールを使う必要がある場合がありますが、まれに(管理ツールとして)使用されていますが、後で使用することを躊躇します。他の場所で使用されています。明示的に、またはしばらく使用されていないときにシステムに許可することによって、それらをアンロードする方法はありますか?コード/モジュールをアンロード

答えて

64

はい、直接モジュールのキャッシュにアクセスすることが可能である:

var name = require.resolve('moduleName'); 
delete require.cache[name]; 

注あなたのコードは、あなたが取り除くしたいこれらのモジュールによって公開されたものは何でもへの参照を運ぶ場合、それはされないことクリーンアップ。

(余談:表面の下に、require.resolverequire.cacheだけで、Moduleはコアモジュールローダであることで、それぞれModule._resolveFilenameModule._cacheにすなわちrequire('module')をプロキシされている。)

+8

これは完全な答えではありません。 index.jsファイルをロードする必要があるものもあれば、ライブラリの実際の部分をロードするものもあります。 たとえば、 ( "async") をロードしようとすると、 "... async/lib/async.js"がロードされますが、 "..async/index.js"がロードされます。 。キャッシュ。 index.jsはasync.jsの親です。したがって、おそらく登録を解除することは可能ですが、複数のモジュールを削除するには再帰的な関数が必要な場合があります。 –

+4

'for(Object.keys(require.cache)のvarキー){delete require.cache [key];}'を実行します。 – Tower

+3

@Tower、それはすべてのモジュールをアンロードします。 'module.parent'などをチェックし、アンロードしたいモジュールだけをアンロードする方が良いかもしれません。例えば、 'util'と' fs'はおそらくアンロードされるべきではありません。 –

3

あなたがアンロード「にこのような何かを行うことができますノードモジュール:

/** 
* Deletes a node module and all associated children 
* from node require cache 
* @param {string} moduleName The name of the module or 
*       absolute/relative path to it 
*/ 
function deleteModule(moduleName) { 
    var solvedName = require.resolve(moduleName), 
    nodeModule = require.cache[solvedName]; 
    if (nodeModule) { 
    for (var i = 0; i < nodeModule.children.length; i++) { 
     var child = nodeModule.children[i]; 
     deleteModule(child.filename); 
    } 
    delete require.cache[solvedName]; 
    } 
} 

ノードモジュールのアンロードは、ノードの要求キャッシュからそのエントリを「削除」していることを意味します。上記のスニペットは、キャッシュおよび関連するすべてのモジュール(子モジュール)から1つのノードモジュールを推移的に削除します。

私の場合、「index.js」と同時に「/lib/.js」が必要でした。私は "index.js"の初期化をテストしたかったので(そこでは/lib/.jsの中で必要とされている唯一の他のモジュール)。キャッシュから "/lib/.js"への別の参照が維持され、モジュール "/lib/.js"がそのファイルから再度ロードされなかったため、キャッシュから "index.js"を削除するだけでは十分ではありませんでした。

上記のコードは、このモジュールが依存する他のモジュールをキャッシュから削除する可能性があります(これは実際に私が望むものですが、 "fs"、 "path"、 "underscore" )。

このメソッドをいつでも拡張して、削除したくないモジュールのリスト、または解決されたモジュールの「パス」に適用できるフィルタのリストを受け入れることができます。あなたは言うことができます:コアノードモジュールを削除しないでください(コアノードモジュール名のリストはnpmパッケージとして利用できます:https://www.npmjs.com/package/node-core-module-names)。あるいは、node_modulesなどの下のパッケージを削除しないでください。機能は同じですが、同じロジックです。

+0

このdeleteModule関数は、循環依存性。 – Halt

関連する問題