Skip to content

Commit e280ed2

Browse files
committed
Ignore more modules on webpack searching
1 parent 8fccda4 commit e280ed2

2 files changed

Lines changed: 60 additions & 65 deletions

File tree

src/webpack/patchWebpack.ts

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { WebpackInstance } from "discord-types/other";
2424

2525
import { traceFunction } from "../debug/Tracer";
2626
import { patches } from "../plugins";
27-
import { _initWebpack, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
27+
import { _initWebpack, _shouldIgnoreModule, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
2828

2929
const logger = new Logger("WebpackInterceptor", "#8caaee");
3030

@@ -173,35 +173,9 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
173173
if (!exports) return;
174174

175175
if (require.c) {
176-
let shouldMakeNonEnumerable = false;
177-
178-
nonEnumerableChecking: {
179-
// There are (at the time of writing) 11 modules exporting the window,
180-
// and also modules exporting DOMTokenList, which breaks webpack finding
181-
// Make these non enumerable to improve search performance and avoid erros
182-
if (exports === window || exports[Symbol.toStringTag] === "DOMTokenList") {
183-
shouldMakeNonEnumerable = true;
184-
break nonEnumerableChecking;
185-
}
176+
const shouldIgnoreModule = _shouldIgnoreModule(exports);
186177

187-
if (typeof exports !== "object") {
188-
break nonEnumerableChecking;
189-
}
190-
191-
if (exports.default === window || exports.default?.[Symbol.toStringTag] === "DOMTokenList") {
192-
shouldMakeNonEnumerable = true;
193-
break nonEnumerableChecking;
194-
}
195-
196-
for (const nested in exports) {
197-
if (exports[nested] === window || exports[nested]?.[Symbol.toStringTag] === "DOMTokenList") {
198-
shouldMakeNonEnumerable = true;
199-
break nonEnumerableChecking;
200-
}
201-
}
202-
}
203-
204-
if (shouldMakeNonEnumerable) {
178+
if (shouldIgnoreModule) {
205179
Object.defineProperty(require.c, id, {
206180
value: require.c[id],
207181
enumerable: false,
@@ -226,17 +200,16 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
226200
if (exports && filter(exports)) {
227201
subscriptions.delete(filter);
228202
callback(exports, id);
229-
} else if (typeof exports === "object") {
230-
if (exports.default && filter(exports.default)) {
203+
}
204+
205+
if (typeof exports !== "object") {
206+
continue;
207+
}
208+
209+
for (const exportKey in exports) {
210+
if (exports[exportKey] && filter(exports[exportKey])) {
231211
subscriptions.delete(filter);
232-
callback(exports.default, id);
233-
} else {
234-
for (const nested in exports) {
235-
if (exports[nested] && filter(exports[nested])) {
236-
subscriptions.delete(filter);
237-
callback(exports[nested], id);
238-
}
239-
}
212+
callback(exports[exportKey], id);
240213
}
241214
}
242215
} catch (err) {

src/webpack/webpack.ts

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ export const filters = {
7171
componentByCode: (...code: CodeFilter): FilterFn => {
7272
const filter = filters.byCode(...code);
7373
return m => {
74-
if (filter(m)) return true;
75-
if (!m.$$typeof) return false;
76-
if (m.type)
77-
return m.type.render
78-
? filter(m.type.render) // memo + forwardRef
79-
: filter(m.type); // memo
80-
if (m.render) return filter(m.render); // forwardRef
74+
let inner = m;
75+
76+
while (inner != null) {
77+
if (filter(inner)) return true;
78+
else if (!inner.$$typeof) return false;
79+
else if (inner.type) inner = inner.type; // memos
80+
else if (inner.render) inner = inner.render; // forwardRefs
81+
else return false;
82+
}
83+
8184
return false;
8285
};
8386
}
@@ -95,6 +98,38 @@ export function _initWebpack(webpackRequire: WebpackInstance) {
9598
cache = webpackRequire.c;
9699
}
97100

101+
// Credits to Zerebos for implementing this in BD, thus giving the idea for us to implement it too
102+
const TypedArray = Object.getPrototypeOf(Int8Array);
103+
104+
function _shouldIgnoreValue(value: any) {
105+
if (value == null) return true;
106+
if (value === window) return true;
107+
if (value === document || value === document.documentElement) return true;
108+
if (value[Symbol.toStringTag] === "DOMTokenList") return true;
109+
if (value instanceof TypedArray) return true;
110+
111+
return false;
112+
}
113+
114+
export function _shouldIgnoreModule(exports: any) {
115+
if (_shouldIgnoreValue(exports)) {
116+
return true;
117+
}
118+
119+
if (typeof exports !== "object") {
120+
return false;
121+
}
122+
123+
let allNonEnumerable = true;
124+
for (const exportKey in exports) {
125+
if (!_shouldIgnoreValue(exports[exportKey])) {
126+
allNonEnumerable = false;
127+
}
128+
}
129+
130+
return allNonEnumerable;
131+
}
132+
98133
let devToolsOpen = false;
99134
if (IS_DEV && IS_DISCORD_DESKTOP) {
100135
// At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed
@@ -121,19 +156,14 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
121156

122157
for (const key in cache) {
123158
const mod = cache[key];
124-
if (!mod.loaded || !mod?.exports) continue;
159+
if (!mod?.loaded || mod.exports == null) continue;
125160

126161
if (filter(mod.exports)) {
127162
return isWaitFor ? [mod.exports, key] : mod.exports;
128163
}
129164

130165
if (typeof mod.exports !== "object") continue;
131166

132-
if (mod.exports.default && filter(mod.exports.default)) {
133-
const found = mod.exports.default;
134-
return isWaitFor ? [found, key] : found;
135-
}
136-
137167
for (const nestedMod in mod.exports) {
138168
const nested = mod.exports[nestedMod];
139169
if (nested && filter(nested)) {
@@ -156,16 +186,15 @@ export function findAll(filter: FilterFn) {
156186
const ret = [] as any[];
157187
for (const key in cache) {
158188
const mod = cache[key];
159-
if (!mod.loaded || !mod?.exports) continue;
189+
if (!mod?.loaded || mod.exports == null) continue;
160190

161191
if (filter(mod.exports))
162192
ret.push(mod.exports);
163-
else if (typeof mod.exports !== "object")
193+
194+
if (typeof mod.exports !== "object")
164195
continue;
165196

166-
if (mod.exports.default && filter(mod.exports.default))
167-
ret.push(mod.exports.default);
168-
else for (const nestedMod in mod.exports) {
197+
for (const nestedMod in mod.exports) {
169198
const nested = mod.exports[nestedMod];
170199
if (nested && filter(nested)) ret.push(nested);
171200
}
@@ -204,7 +233,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
204233
outer:
205234
for (const key in cache) {
206235
const mod = cache[key];
207-
if (!mod.loaded || !mod?.exports) continue;
236+
if (!mod?.loaded || mod.exports == null) continue;
208237

209238
for (let j = 0; j < length; j++) {
210239
const filter = filters[j];
@@ -221,13 +250,6 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
221250
if (typeof mod.exports !== "object")
222251
continue;
223252

224-
if (mod.exports.default && filter(mod.exports.default)) {
225-
results[j] = mod.exports.default;
226-
filters[j] = undefined;
227-
if (++found === length) break outer;
228-
break;
229-
}
230-
231253
for (const nestedMod in mod.exports) {
232254
const nested = mod.exports[nestedMod];
233255
if (nested && filter(nested)) {

0 commit comments

Comments
 (0)