@@ -8,23 +8,27 @@ import { Logger } from "@utils/Logger";
88import { canonicalizeMatch } from "@utils/patches" ;
99import * as Webpack from "@webpack" ;
1010import { wreq } from "@webpack" ;
11-
12- const LazyChunkLoaderLogger = new Logger ( "LazyChunkLoader" ) ;
11+ import { AnyModuleFactory , ModuleFactory } from "webpack" ;
1312
1413export async function loadLazyChunks ( ) {
14+ const LazyChunkLoaderLogger = new Logger ( "LazyChunkLoader" ) ;
15+
1516 try {
1617 LazyChunkLoaderLogger . log ( "Loading all chunks..." ) ;
1718
18- const validChunks = new Set < number > ( ) ;
19- const invalidChunks = new Set < number > ( ) ;
20- const deferredRequires = new Set < number > ( ) ;
19+ const validChunks = new Set < PropertyKey > ( ) ;
20+ const invalidChunks = new Set < PropertyKey > ( ) ;
21+ const deferredRequires = new Set < PropertyKey > ( ) ;
2122
22- let chunksSearchingResolve : ( value : void | PromiseLike < void > ) => void ;
23+ let chunksSearchingResolve : ( value : void ) => void ;
2324 const chunksSearchingDone = new Promise < void > ( r => chunksSearchingResolve = r ) ;
2425
2526 // True if resolved, false otherwise
2627 const chunksSearchPromises = [ ] as Array < ( ) => boolean > ;
2728
29+ /* This regex loads all language packs which makes webpack finds testing extremely slow, so for now, lets use one which doesnt include those
30+ const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("?[^)]+?"?\)[^\]]*?)(?:\]\))?)\.then\(\i(?:\.\i)?\.bind\(\i,"?([^)]+?)"?(?:,[^)]+?)?\)\)/g);
31+ */
2832 const LazyChunkRegex = canonicalizeMatch ( / (?: (?: P r o m i s e \. a l l \( \[ ) ? ( \i \. e \( " ? [ ^ ) ] + ?" ? \) [ ^ \] ] * ?) (?: \] \) ) ? ) \. t h e n \( \i \. b i n d \( \i , " ? ( [ ^ ) ] + ?) " ? \) \) / g) ;
2933
3034 let foundCssDebuggingLoad = false ;
@@ -34,12 +38,15 @@ export async function loadLazyChunks() {
3438 const hasCssDebuggingLoad = foundCssDebuggingLoad ? false : ( foundCssDebuggingLoad = factoryCode . includes ( ".cssDebuggingEnabled&&" ) ) ;
3539
3640 const lazyChunks = factoryCode . matchAll ( LazyChunkRegex ) ;
37- const validChunkGroups = new Set < [ chunkIds : number [ ] , entryPoint : number ] > ( ) ;
41+ const validChunkGroups = new Set < [ chunkIds : PropertyKey [ ] , entryPoint : PropertyKey ] > ( ) ;
3842
3943 const shouldForceDefer = false ;
4044
4145 await Promise . all ( Array . from ( lazyChunks ) . map ( async ( [ , rawChunkIds , entryPoint ] ) => {
42- const chunkIds = rawChunkIds ? Array . from ( rawChunkIds . matchAll ( Webpack . ChunkIdsRegex ) ) . map ( m => Number ( m [ 1 ] ) ) : [ ] ;
46+ const chunkIds = rawChunkIds ? Array . from ( rawChunkIds . matchAll ( Webpack . ChunkIdsRegex ) ) . map ( m => {
47+ const numChunkId = Number ( m [ 1 ] ) ;
48+ return Number . isNaN ( numChunkId ) ? m [ 1 ] : numChunkId ;
49+ } ) : [ ] ;
4350
4451 if ( chunkIds . length === 0 ) {
4552 return ;
@@ -74,15 +81,16 @@ export async function loadLazyChunks() {
7481 }
7582
7683 if ( ! invalidChunkGroup ) {
77- validChunkGroups . add ( [ chunkIds , Number ( entryPoint ) ] ) ;
84+ const numEntryPoint = Number ( entryPoint ) ;
85+ validChunkGroups . add ( [ chunkIds , Number . isNaN ( numEntryPoint ) ? entryPoint : numEntryPoint ] ) ;
7886 }
7987 } ) ) ;
8088
8189 // Loads all found valid chunk groups
8290 await Promise . all (
8391 Array . from ( validChunkGroups )
8492 . map ( ( [ chunkIds ] ) =>
85- Promise . all ( chunkIds . map ( id => wreq . e ( id as any ) . catch ( ( ) => { } ) ) )
93+ Promise . all ( chunkIds . map ( id => wreq . e ( id ) ) )
8694 )
8795 ) ;
8896
@@ -94,7 +102,7 @@ export async function loadLazyChunks() {
94102 continue ;
95103 }
96104
97- if ( wreq . m [ entryPoint ] ) wreq ( entryPoint as any ) ;
105+ if ( wreq . m [ entryPoint ] ) wreq ( entryPoint ) ;
98106 } catch ( err ) {
99107 console . error ( err ) ;
100108 }
@@ -122,41 +130,44 @@ export async function loadLazyChunks() {
122130 } , 0 ) ;
123131 }
124132
125- Webpack . factoryListeners . add ( factory => {
133+ function factoryListener ( factory : AnyModuleFactory | ModuleFactory ) {
126134 let isResolved = false ;
127- searchAndLoadLazyChunks ( factory . toString ( ) ) . then ( ( ) => isResolved = true ) ;
135+ searchAndLoadLazyChunks ( String ( factory ) )
136+ . then ( ( ) => isResolved = true )
137+ . catch ( ( ) => isResolved = true ) ;
128138
129139 chunksSearchPromises . push ( ( ) => isResolved ) ;
130- } ) ;
140+ }
131141
142+ Webpack . factoryListeners . add ( factoryListener ) ;
132143 for ( const factoryId in wreq . m ) {
133- let isResolved = false ;
134- searchAndLoadLazyChunks ( wreq . m [ factoryId ] . toString ( ) ) . then ( ( ) => isResolved = true ) ;
135-
136- chunksSearchPromises . push ( ( ) => isResolved ) ;
144+ factoryListener ( wreq . m [ factoryId ] ) ;
137145 }
138146
139147 await chunksSearchingDone ;
148+ Webpack . factoryListeners . delete ( factoryListener ) ;
140149
141150 // Require deferred entry points
142151 for ( const deferredRequire of deferredRequires ) {
143- wreq ! ( deferredRequire as any ) ;
152+ wreq ( deferredRequire ) ;
144153 }
145154
146155 // All chunks Discord has mapped to asset files, even if they are not used anymore
147- const allChunks = [ ] as number [ ] ;
156+ const allChunks = [ ] as PropertyKey [ ] ;
148157
149158 // Matches "id" or id:
150- for ( const currentMatch of wreq ! . u . toString ( ) . matchAll ( / (?: " ( [ \d e E ] + ?) " (? ! [ , } ] ) ) | (?: ( [ \d e E ] + ?) : ) / g) ) {
159+ for ( const currentMatch of String ( wreq . u ) . matchAll ( / (?: " ( [ \d e E ] + ?) " (? ! [ , } ] ) ) | (?: ( [ \d e E ] + ?) : ) / g) ) {
151160 const id = currentMatch [ 1 ] ?? currentMatch [ 2 ] ;
152161 if ( id == null ) continue ;
153162
154- allChunks . push ( Number ( id ) ) ;
163+ const numId = Number ( id ) ;
164+ allChunks . push ( Number . isNaN ( numId ) ? id : numId ) ;
155165 }
156166
157167 if ( allChunks . length === 0 ) throw new Error ( "Failed to get all chunks" ) ;
158168
159- // Chunks that are not loaded (not used) by Discord code anymore
169+ // Chunks which our regex could not catch to load
170+ // It will always contain WebWorker assets, and also currently contains some language packs which are loaded differently
160171 const chunksLeft = allChunks . filter ( id => {
161172 return ! ( validChunks . has ( id ) || invalidChunks . has ( id ) ) ;
162173 } ) ;
@@ -166,12 +177,9 @@ export async function loadLazyChunks() {
166177 . then ( r => r . text ( ) )
167178 . then ( t => t . includes ( "importScripts(" ) ) ;
168179
169- // Loads and requires a chunk
180+ // Loads the chunk. Currently this only happens with the language packs which are loaded differently
170181 if ( ! isWorkerAsset ) {
171- await wreq . e ( id as any ) ;
172- // Technically, the id of the chunk does not match the entry point
173- // But, still try it because we have no way to get the actual entry point
174- if ( wreq . m [ id ] ) wreq ( id as any ) ;
182+ await wreq . e ( id ) ;
175183 }
176184 } ) ) ;
177185
0 commit comments