fix: deleteModule is unloading even shared modules

Massimo Melina committed Jan 8, 2022 at 16:19 UTC 44dcf0f7d5d39ecaac259121783fe4805de11f93
2 files changed +22 -9
src/plugins.ts
+22 -8
@@ -7,6 +7,7 @@ import { PLUGINS_PUB_URI } from './const'
7 import mime from 'mime-types'
8 import Koa from 'koa'
9 import { WatchLoadCanceller } from './watchLoad'
10 +import { getOrSet, wantArray } from './misc'
11
12 const PATH = 'plugins'
13
@@ -124,7 +125,7 @@ async function resolveImport(x: Record<string,any>, basePath: string) {
125 cancellers.push(watchLoad(path, async () => {
126 try {
127 x[k] = (await import(path)).default
127 - deleteModule(path) // avoid caching
128 + deleteModule(require.resolve(path)) // avoid caching
129 console.log('plugin imported', fn)
130 } catch (e) {
131 console.log('plugin error importing', fn, String(e))
@@ -140,11 +141,24 @@ async function resolveImport(x: Record<string,any>, basePath: string) {
141 }
142 }
143
143 -function deleteModule(name: string) {
144 - let solvedName = require.resolve(name)
145 - let mod = require.cache[solvedName]
146 - if (!mod) return
147 - for (const child of mod.children)
148 - deleteModule(child.filename)
149 - delete require.cache[solvedName]
144 +function deleteModule(id: string) {
145 + const { cache } = require
146 + // build reversed map of dependencies
147 + const requiredBy: Record<string,string[]> = { '.':['.'] } // don't touch main entry
148 + for (const k in cache)
149 + if (k !== id)
150 + for (const child of wantArray(cache[k]?.children))
151 + getOrSet(requiredBy, child.id, ()=> [] as string[]).push(k)
152 + const deleted: string[] = []
153 + recur(id)
154 +
155 + function recur(id: string) {
156 + let mod = cache[id]
157 + if (!mod) return
158 + delete cache[id]
159 + deleted.push(id)
160 + for (const child of mod.children)
161 + if (! _.difference(requiredBy[child.id], deleted).length)
162 + recur(child.id)
163 + }
164 }
todo.md
-1
@@ -1,5 +1,4 @@
1 # To do
2 -- fix: deleteModule is unloading even shared modules
2 - fix: icons are not being cached
3 - fix: plugins folder is not found
4 - anti-csrf