@@ -309,10 +309,43 @@ export default defineConfig({
309309
310310 Content = ErrorListeners + "\n" + Content ;
311311
312- // 8b: Wrap result.main(configuration) with try/catch + await
312+ // 8b: Add checkpoints inside load() to trace the hang
313+ Content = Content . replace (
314+ "const configuration2 = await resolveWindowConfiguration()" ,
315+ `console.log("[workbench.js] WB1: calling resolveWindowConfiguration");const configuration2 = await resolveWindowConfiguration()` ,
316+ ) ;
317+ // 8b-fix: Ensure profile URIs exist for reviveProfile().
318+ // Wind's ResolveConfiguration may have location:undefined
319+ // due to Vite cache. Fix the configuration in-place here.
320+ Content = Content . replace (
321+ "setupNLS(configuration2)" ,
322+ [
323+ `if(configuration2.profiles){` ,
324+ `const _S="vscode-userdata";` ,
325+ `const _fix=(p)=>{if(!p)return;` ,
326+ `if(!p.location)p.location={scheme:_S,path:"/User/profiles/"+(p.id||"default")};` ,
327+ `if(!p.promptsHome)p.promptsHome={scheme:_S,path:"/User/prompts"};` ,
328+ `if(!p.extensionsResource)p.extensionsResource={scheme:_S,path:"/User/extensions.json"};` ,
329+ `if(!p.mcpResource)p.mcpResource={scheme:_S,path:"/User/mcp.json"};` ,
330+ `};` ,
331+ `_fix(configuration2.profiles.profile);` ,
332+ `if(Array.isArray(configuration2.profiles.all))configuration2.profiles.all.forEach(_fix);` ,
333+ `}` ,
334+ `console.log("[workbench.js] WB2: config resolved, calling setupNLS");setupNLS(configuration2)` ,
335+ ] . join ( "" ) ,
336+ ) ;
337+ Content = Content . replace (
338+ "const result2 = await import(workbenchUrl)" ,
339+ `console.log("[workbench.js] WB3: importing workbench module:",workbenchUrl);const result2 = await import(workbenchUrl)` ,
340+ ) ;
341+ Content = Content . replace (
342+ "return { result: result2, configuration: configuration2 }" ,
343+ `console.log("[workbench.js] WB4: import done");return { result: result2, configuration: configuration2 }` ,
344+ ) ;
345+ // 8c: Wrap result.main(configuration) with try/catch + await
313346 Content = Content . replace (
314347 "result.main(configuration)" ,
315- `try{await result.main(configuration)}catch(_e){console.error("[workbench.js] main() failed:",_e);if(_e&&_e.stack)console.error(_e.stack)}` ,
348+ `console.log("[workbench.js] WB5: calling main()"); try{await result.main(configuration)}catch(_e){console.error("[workbench.js] main() failed:",_e);if(_e&&_e.stack)console.error(_e.stack)}` ,
316349 ) ;
317350
318351 await writeFile ( WorkbenchJS , Content , "utf-8" ) ;
@@ -328,6 +361,126 @@ export default defineConfig({
328361 }
329362 }
330363
364+ // Step 9: When Electron=true, patch desktop.main.js with
365+ // checkpoint logging to trace where initServices() hangs.
366+ if ( process . env [ "Electron" ] === "true" ) {
367+ const DesktopMainJS = join (
368+ Destination ,
369+ "workbench" ,
370+ "electron-browser" ,
371+ "desktop.main.js" ,
372+ ) ;
373+ try {
374+ let Content = await readFile (
375+ DesktopMainJS ,
376+ "utf-8" ,
377+ ) ;
378+ // Patches use IIFE wrappers (()=>{log;return expr})() for
379+ // expression contexts, and statement prepends for statement contexts.
380+ // CP5-7 are inside Promise.all([...]) so we log BEFORE the array.
381+ const Patches : [ string , string ] [ ] = [
382+ [
383+ "new ElectronIPCMainProcessService(this.configuration.windowId)" ,
384+ `(()=>{console.log("[desktop.main] CP1: creating MainProcessService");return new ElectronIPCMainProcessService(this.configuration.windowId)})()` ,
385+ ] ,
386+ [
387+ "new NativeWorkbenchEnvironmentService(this.configuration, productService)" ,
388+ `(()=>{console.log("[desktop.main] CP2: creating EnvironmentService");return new NativeWorkbenchEnvironmentService(this.configuration, productService)})()` ,
389+ ] ,
390+ [
391+ "new SharedProcessService(this.configuration.windowId, logService)" ,
392+ `(()=>{console.log("[desktop.main] CP3: creating SharedProcessService");return new SharedProcessService(this.configuration.windowId, logService)})()` ,
393+ ] ,
394+ [
395+ "new FileService(logService)" ,
396+ `(()=>{console.log("[desktop.main] CP4: creating FileService");return new FileService(logService)})()` ,
397+ ] ,
398+ [
399+ "const [configurationService, storageService] = await Promise.all([" ,
400+ `console.log("[desktop.main] CP5: entering Promise.all (workspace+storage+keyboard)");const [configurationService, storageService] = await Promise.all([` ,
401+ ] ,
402+ [
403+ "const workbench = new Workbench(" ,
404+ `console.log("[desktop.main] CP6: initServices DONE, creating Workbench");const workbench = new Workbench(` ,
405+ ] ,
406+ ] ;
407+ for ( const [ Search , Replace ] of Patches ) {
408+ if ( Content . includes ( Search ) ) {
409+ Content = Content . replace ( Search , Replace ) ;
410+ }
411+ }
412+ await writeFile ( DesktopMainJS , Content , "utf-8" ) ;
413+ console . log (
414+ "[CopyVSCode] Step 9: Patched desktop.main.js with checkpoint logging" ,
415+ ) ;
416+ } catch ( Error ) {
417+ console . warn (
418+ "[CopyVSCode] Step 9: desktop.main.js checkpoint patching failed:" ,
419+ Error ,
420+ ) ;
421+ }
422+ }
423+
424+ // Step 10: When Electron=true, replace workbench.desktop.main.js
425+ // static imports with sequential dynamic imports that log progress.
426+ // Static imports of 3385 modules overwhelm WKWebView's module loader.
427+ if ( process . env [ "Electron" ] === "true" ) {
428+ const DesktopBarrelJS = join (
429+ Destination ,
430+ "workbench" ,
431+ "workbench.desktop.main.js" ,
432+ ) ;
433+ try {
434+ const Content = await readFile (
435+ DesktopBarrelJS ,
436+ "utf-8" ,
437+ ) ;
438+ // Extract side-effect import paths: import './foo.js';
439+ const SideEffectImports : string [ ] = [ ] ;
440+ const SideEffectRE =
441+ / ^ i m p o r t \s + [ ' " ] ( [ ^ ' " ] + ) [ ' " ] \s * ; ? \s * $ / gm;
442+ let Match ;
443+ while (
444+ ( Match = SideEffectRE . exec ( Content ) ) !== null
445+ ) {
446+ SideEffectImports . push ( Match [ 1 ] ) ;
447+ }
448+ // Build: static named imports at top, then dynamic side-effect
449+ // imports, then registerSingleton + export at bottom.
450+ const Lines = [
451+ `// Sequential dynamic import loader (Step 10)` ,
452+ `import { registerSingleton } from '../platform/instantiation/common/extensions.js';` ,
453+ `import { IUserDataInitializationService, UserDataInitializationService } from './services/userData/browser/userDataInit.js';` ,
454+ `import { SyncDescriptor } from '../platform/instantiation/common/descriptors.js';` ,
455+ `` ,
456+ `console.log("[workbench.desktop.main] Loading ${ SideEffectImports . length } modules sequentially...");` ,
457+ `const _t0 = performance.now();` ,
458+ `let _n = 0;` ,
459+ ...SideEffectImports . map (
460+ ( Path : string , I : number ) =>
461+ `try{await import('${ Path } ');_n++;${ I % 10 === 0 ? `console.log("[workbench.desktop.main] "+_n+"/${ SideEffectImports . length } : ${ Path } ");` : "" } }catch(_e){console.error("[workbench.desktop.main] FAILED #${ I } : ${ Path } ",_e)}` ,
462+ ) ,
463+ `console.log("[workbench.desktop.main] Done: "+_n+"/${ SideEffectImports . length } in "+(performance.now()-_t0).toFixed(0)+"ms");` ,
464+ `` ,
465+ `registerSingleton(IUserDataInitializationService, new SyncDescriptor(UserDataInitializationService, [[]], true));` ,
466+ `export { main } from './electron-browser/desktop.main.js';` ,
467+ ] ;
468+ await writeFile (
469+ DesktopBarrelJS ,
470+ Lines . join ( "\n" ) ,
471+ "utf-8" ,
472+ ) ;
473+ console . log (
474+ `[CopyVSCode] Step 10: Replaced ${ SideEffectImports . length } static imports with sequential dynamic imports` ,
475+ ) ;
476+ } catch ( Error ) {
477+ console . warn (
478+ "[CopyVSCode] Step 10: dynamic import replacement failed:" ,
479+ Error ,
480+ ) ;
481+ }
482+ }
483+
331484 console . log ( "[CopyVSCode] ✓ Assets ready in Target/" ) ;
332485 } ,
333486 } ,
0 commit comments