Ответ
Да, это возможно через глобальный объект require.cache. Он представляет собой объект, где ключами являются абсолютные пути к модулям, а значениями — сами закешированные модули.
Как очистить кеш конкретного модуля:
const pathToModule = require.resolve('./my-config.js');
delete require.cache[pathToModule];
// Следующий require('./my-config.js') загрузит модуль заново.
Как очистить весь кеш модулей:
Object.keys(require.cache).forEach((cacheKey) => {
delete require.cache[cacheKey];
});
Важные предостережения из практики:
- Сброс состояния: Если модуль экспортирует объект с состоянием (синглтон, кэш в памяти), его очистка приведет к потере этого состояния, что может сломать логику приложения.
- Утечки ресурсов: Если модуль инициализирует таймеры, открывает соединения с БД или создает другие ресурсы, их необходимо корректно закрывать перед удалением из кеша, иначе возникнут утечки.
- Производительность: Постоянная перезагрузка модулей негативно скажется на производительности.
Практическое применение: Я использовал очистку кеша в основном в двух сценариях:
- При разработке инструментов CLI, где нужно гарантировать загрузку самой свежей версии пользовательского конфига при каждом вызове.
- В режиме разработки «горячей перезагрузки» (hot reload) для серверов, где перезагрузка всего процесса нежелательна. Однако для этого сейчас чаще используются специализированные решения вроде
nodemonилиnode --watch(с Node.js v18.11.0+).
Ответ 18+ 🔞
Ах ты ж ёпта, ну и тема подкинули! Сижу тут, кофе попиваю, и вдруг — бац! — вопрос про require.cache. Ну, мужик, это ж классика, как водка с огурцом! Слушай сюда, сейчас всё разжуем.
Вот представь: Node.js, он такой хитрая жопа, когда модуль загружает — в кеш его пихает, чтобы второй раз не париться. А кеш этот — обычный объект, require.cache, где ключики — пути к файлам, а значения — уже скомпилированные модульчики. Красота, да? Но иногда надо, чтобы он забыл. Например, конфиг переписал, а приложение упёртое, старое не отпускает.
Так вот, если хочешь конкретный модуль заставить перезагрузиться — делай так:
const pathToModule = require.resolve('./my-config.js');
delete require.cache[pathToModule];
// Теперь следующий require('./my-config.js') будет как первый раз — свеженький, с пылу с жару.
А если совсем крыша поехала и надо всё с нуля — можно и всю избушку подмести:
Object.keys(require.cache).forEach((cacheKey) => {
delete require.cache[cacheKey];
});
Но тут, чувак, внимание, блядь! Это не игрушки. Представь, модуль-то мог уже наделать делов: глобальный объект-синглтон создал, к базе подключился, таймеры настроил. Ты его из кеша выкинешь — а он, сука, как призрак, свои таймеры-то оставил тикать, соединения висеть. Утечка ресурсов — и приложение потом как пьяный ёжик, ебать копать, ползает.
На практике я эту фишку юзал, в основном, в двух случаях, как отличник-извращенец:
- В разных CLI-шниках, которые я писал. Там надо было, чтобы конфиг пользователя каждый раз читался заново, а не как вчерашний борщ. Иначе доверия ебать ноль.
- Для горячей перезагрузки (hot reload) на сервере в режиме разработки. Раньше это была магия, но сейчас-то, слава богу, есть
nodemonили встроенная watch-режима в Node.js. Так что не изобретай велосипед, а то получится манда с ушами.
Короче, инструмент мощный, но острый. Бери в руки, только если точно знаешь, зачем. А то можно так взъебнуть приложение, что сам от себя охуеешь.