webpack patcher: support new Discord bundler changes

This commit is contained in:
Nuckyz 2026-01-22 16:39:07 -03:00 committed by Vendicated
parent 44bdb60bb6
commit 8c81e5d27e
No known key found for this signature in database
GPG key ID: D66986BAF75ECF18
3 changed files with 22 additions and 15 deletions

View file

@ -45,8 +45,8 @@ export async function loadLazyChunks() {
const chunksSearchPromises = [] as Array<() => boolean>;
// This regex loads all language packs which makes webpack finds testing extremely slow, so for now, we prioritize using the one which doesnt include those
const CompleteLazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g);
const PartialLazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
const CompleteLazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?((?:\i\.e\("?[^)]+?"?\),?)+?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g);
const PartialLazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?((?:\i\.e\("?[^)]+?"?\),?)+?)(?:\]\))?)\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/g);
let foundCssDebuggingLoad = false;

View file

@ -495,8 +495,11 @@ function runFactoryWithWrap(patchedFactory: PatchedModuleFactory, thisArg: unkno
* @returns The patched module factory
*/
function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory): PatchedModuleFactory {
const originalFactoryCode = String(originalFactory);
const isArrowFunction = originalFactoryCode.startsWith("(");
// 0, prefix to turn it into an expression: 0,function(){} would be invalid syntax without the 0,
let code: string = "0," + String(originalFactory);
let code = "0," + (!isArrowFunction ? "function" : "") + originalFactoryCode.slice(originalFactoryCode.indexOf("("));
let patchedSource = code;
let patchedFactory = originalFactory;
@ -586,7 +589,7 @@ function patchFactory(moduleId: PropertyKey, originalFactory: AnyModuleFactory):
}
code = newCode;
patchedSource = `// Webpack Module ${String(moduleId)} - Patched by ${pluginsList.join(", ")}\n${newCode}\n//# sourceURL=file:///WebpackModule${String(moduleId)}`;
patchedSource = `// Webpack Module ${String(moduleId)} - Patched by ${pluginsList.join(", ")}\n${code}\n//# sourceURL=file:///WebpackModule${String(moduleId)}`;
patchedFactory = (0, eval)(patchedSource);
if (!patchedBy.has(patch.plugin)) {

View file

@ -21,7 +21,7 @@ import { LazyComponent } from "@utils/lazyReact";
import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches";
import type { FluxStore } from "@vencord/discord-types";
import type { ModuleExports, WebpackRequire } from "@vencord/discord-types/webpack";
import type { ModuleExports, ModuleFactory, WebpackRequire } from "@vencord/discord-types/webpack";
import { traceFunction } from "../debug/Tracer";
import type { AnyModuleFactory, AnyWebpackRequire } from "./types";
@ -626,7 +626,7 @@ export function mapMangledModuleLazy<S extends string>(code: string | RegExp | C
return proxyLazy(() => mapMangledModule(code, mappers, includeBlacklistedExports));
}
export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/;
export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?((?:\i\.e\("?[^)]+?"?\),?)+?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"?([^)]+?)"?\)\)/;
export const ChunkIdsRegex = /\("([^"]+?)"\)/g;
/**
@ -769,20 +769,24 @@ export function search(...code: CodeFilter) {
* to view a massive file. extract then returns the extracted module so you can jump to it.
* As mentioned above, note that this extracted module is not actually used,
* so putting breakpoints or similar will have no effect.
* @param id The id of the module to extract
* @param moduleId The id of the module to extract
*/
export function extract(id: string | number) {
const mod = wreq.m[id] as Function;
if (!mod) return null;
export function extract(moduleId: PropertyKey) {
const originalFactory = wreq.m[moduleId];
if (!originalFactory) return null;
const originalFactoryCode = String(originalFactory);
const isArrowFunction = originalFactoryCode.startsWith("(");
const wrappedCode = "0," + (!isArrowFunction ? "function" : "") + originalFactoryCode.slice(originalFactoryCode.indexOf("("));
const code = `
// [EXTRACTED] WebpackModule${id}
// [EXTRACTED] WebpackModule${String(moduleId)}
// WARNING: This module was extracted to be more easily readable.
// This module is NOT ACTUALLY USED! This means putting breakpoints will have NO EFFECT!!
0,${mod.toString()}
//# sourceURL=file:///ExtractedWebpackModule${id}
0,${wrappedCode}
//# sourceURL=file:///ExtractedWebpackModule${String(moduleId)}
`;
const extracted = (0, eval)(code);
return extracted as Function;
return (0, eval)(code) as ModuleFactory;
}