"Выгрузка кода/модулей"
Я заинтересован в том, есть ли хороший способ выгрузить модуль после его использования. У меня есть несколько случаев, когда мне нужно использовать модули, которые загружают много кода, но используются они редко (например, как админские инструменты). Я колеблюсь, стоит ли их использовать, потому что после этого, по всей видимости, они будут просто занимать память, которая могла бы быть использована более эффективно. Существует ли способ выгрузить их, либо явно, либо позволив системе сделать это, когда они не использовались некоторое время?
2 ответ(ов)
Да, действительно, можно напрямую получить доступ к кэшу модулей:
var name = require.resolve('moduleName');
delete require.cache[name];
Имейте в виду, что если в вашем коде осталась ссылка на то, что было экспортировано этими модулями, оно не будет очищено.
В дополнение: На самом деле, require.resolve
и require.cache
являются прокси-подходами к Module._resolveFilename
и Module._cache
соответственно, где Module
является основным загрузчиком модулей, т.е. require('module')
.
Вы можете сделать что-то подобное, чтобы "разгрузить" модуль Node.js:
/**
* Удаляет модуль Node.js и все связанные с ним дочерние модули
* из кеша require Node.js
* @param {string} moduleName Имя модуля или
* абсолютный/относительный путь к нему
*/
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];
}
}
"Разгрузка" модуля Node.js означает "удаление" его записи из кеша require. В приведенном выше фрагменте кода производится рекурсивное удаление одного модуля из кеша и всех связанных с ним модулей (дочерних модулей).
В моем случае я требовал "index.js", который одновременно требовал "/lib/.js". Я хотел протестировать инициализацию "index.js" (и, следовательно, единственный другой модуль, который требовался в нем, - это /lib/.js). Удаление "index.js" из кеша было недостаточно, поскольку кеш сохранял отдельную ссылку на "/lib/.js", и это приводило к тому, что модуль "/lib/.js" не загружался снова из файла.
Код выше, безусловно, может удалить из кеша другие модули, от которых зависит этот модуль (что, собственно, я и хотел, НО вы можете не захотеть делать это для других модулей, таких как "fs", "path" или даже "underscore").
Вы всегда можете расширить этот метод, чтобы он принимал список модулей, которые вы не хотите удалять, или фильтр, который вы могли бы применить к "пути" разрешенного модуля. Вы можете сказать: не удалять основные модули Node.js (список имен основных модулей доступен в виде npm-пакета: https://www.npmjs.com/package/node-core-module-names) или не удалять любые пакеты из node_modules и т.д. Этот фильтр может быть реализован внутри функции, но логика останется такой же.
Как узнать версию установленного npm пакета?
Как в Node.js "подключить" функции из других файлов?
Как задать переменные окружения из файла package.json?
Самый быстрый способ скопировать файл в Node.js
Как остановить Babel от трансформации 'this' в 'undefined' и добавления "use strict"