vscode源碼分析【八】加載第一個畫面


第一篇: vscode源碼分析【一】從源碼運行vscode
第二篇:vscode源碼分析【二】程序的啟動邏輯,第一個窗口是如何創建的
第三篇:vscode源碼分析【三】程序的啟動邏輯,性能問題的追蹤
第四篇:vscode源碼分析【四】程序啟動的邏輯,最初創建的服務
第五篇:vscode源碼分析【五】事件分發機制
第六篇:vscode源碼分析【六】服務實例化和單例的實現
第七篇:vscode源碼分析【七】主進程啟動消息通信服務
先復習一下!
在第一節中,我們提到:
app.ts(src\vs\code\electron-main\app.ts)的openFirstWindow方法中,
有個WindowsMainService

const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // TODO@Joao: unfold this
//...
windowsMainService.open({
			context,
			cli: args,
			forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']),
			diffMode: args.diff,
			noRecentEntry,
			waitMarkerFileURI,
			initialStartup: true
		});

這個WindowsMainService
(接口文件:src\vs\platform\windows\electron-main\windows.ts)
(實例文件:src\vs\code\electron-main\windows.ts)
接口和實例的關系,是在這里做成的(407行):

services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv]));

實例的open方法最關鍵的一句話是:

const usedWindows = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, fileInputs, foldersToAdd);

在doOpen方法里調用了:this.openInBrowserWindow,並把這個窗口保存到usedWindows里去了;
(如果已經有打開的窗口,那么就用現成的窗口打開新的內容)

usedWindows.push(this.openInBrowserWindow({
					userEnv: openConfig.userEnv,
					cli: openConfig.cli,
					initialStartup: openConfig.initialStartup,
					fileInputs: fileInputsForWindow,
					remoteAuthority,
					forceNewWindow: true,
					forceNewTabbedWindow: openConfig.forceNewTabbedWindow,
					emptyWindowBackupInfo
				}));

我們接下來去看看openInBrowserWindow做了什么
其中最關鍵的一句:

window = this.instantiationService.createInstance(CodeWindow, {
				state,
				extensionDevelopmentPath: configuration.extensionDevelopmentPath,
				isExtensionTestHost: !!configuration.extensionTestsPath
			});

CodeWindow的構造函數里,調用了createBrowserWindow方法,在這個方法里創建了我們的Electron的BrowserWindow
(src\vs\code\electron-main\window.ts)

this._win = new BrowserWindow(options);

好!窗口創建出來了,那么窗口中的內容呢?按道理來說應該加載一個頁面用於展現UI的呀?
復習結束,下面是新的內容
我們接着去看openInBrowserWindow方法的后面的內容,發現有這么一句:

		if (window.isReady) {
			this.lifecycleService.unload(window, UnloadReason.LOAD).then(veto => {
				if (!veto) {
					this.doOpenInBrowserWindow(window!, configuration, options);
				}
			});
		} else {
			this.doOpenInBrowserWindow(window, configuration, options);
		}

在doOpenInBrowserWindow里,調用了

window.load(configuration);

OK!我們再回到CodeWindow的類型里去,看看load方法做了什么
我們看到了這一句:

this._win.loadURL(this.getUrl(configuration));

他們在getUrl方法里做了一堆跟URL一點關系也沒有的事情
比如說:設置窗口的縮放級別,設置全屏、設置窗口ID之類的
做完這些無關的事情,有跳進了另一個函數:

let configUrl = this.doGetUrl(config);
return configUrl;

在這個doGetUrl里只有一句話:

return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;

這個require.toUrl方法采用通用的模塊ID路徑轉化規則,將模塊ID字符解析成URL路徑;
注意:file:///協議開頭的URL路徑;
至此,這個窗口總算顯示出了一個畫面!
這個頁面body里並沒有任何東西;只加載了一個js文件

<script src="workbench.js"></script>

后面我們再繼續聊這個js文件的邏輯!




 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM